我正在使用SSO登录和.net核心Web API开发Angular 6应用程序。该代码首次在/ token网址上到达后端,这是一项后期操作。在这种情况下,我该如何做防伪。请说明令牌转移的流程
答案 0 :(得分:1)
我不确定这是否是您要寻找的,但是我将尽力解释在类似情况下我是如何实现的。
首先Angular内置了用于XSRF处理的助手:
所以最困难的部分是在api级别上创建自定义XSRF中间件。
前段时间,我为其中一个应用程序创建了该应用程序,该应用程序的前端是Angular 6,后端是ASP.NET Core WebApi。
有帮助的文章
您的中间件可能如下所示:
public class AntiForgeryTokenMiddleware
{
private readonly RequestDelegate _next;
private readonly IAntiforgery _antiforgery;
public AntiForgeryTokenMiddleware(RequestDelegate next, IAntiforgery antiforgery)
{
_next = next;
_antiforgery = antiforgery;
}
public Task Invoke(HttpContext context)
{
if (context.Request.Path.Value.IndexOf("/your api endpoint, e.g. /api", StringComparison.OrdinalIgnoreCase) != -1)
{
var tokens = _antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false, Secure = false });
}
return _next(context);
}
}
然后按照提到的文章,您必须将其添加到Startup类的ConfigureServices方法中的服务中:
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
并在Configure方法中使用它:
app.UseAntiforgeryToken();
当然要利用它,您必须使用[ValidateAntiForgeryToken]属性装饰api方法。
然后在Angular应用中,您可以创建HttpInterceptor以仅在需要时发送令牌。
@Injectable()
export class XsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {}
private actions: string[] = ["POST", "PUT", "DELETE"];
private forbiddenActions: string[] = ["HEAD", "OPTIONS"];
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token = this.tokenExtractor.getToken();
let permitted = this.findByActionName(request.method, this.actions);
let forbidden = this.findByActionName(request.method, this.forbiddenActions);;
if (permitted !== undefined && forbidden === undefined && token !== null) {
request = request.clone({ setHeaders: { "X-XSRF-TOKEN": token } });
}
return next.handle(request);
}
private findByActionName(name: string, actions: string[]): string {
return actions.find(action => action.toLocaleLowerCase() === name.toLocaleLowerCase());
}
}
答案 1 :(得分:0)
这个问题很旧,但是我的解决方案可以帮助某人。对我们有用的东西:
HttpXsrfTokenInterceptor ,它设置了 X-XSRF-TOKEN 标头。当然,cookie必须在 XSRF-TOKEN
下包含令牌:基本上是上述方法,使用domstamand's方法。但是,这很重要,您必须将验证操作添加到中间件中。显然,使用您的自定义middlaware可以关闭.net核心防伪服务的OOB验证。因此,更新 Invoke 方法的代码后,应如下所示:
public Task Invoke(HttpContext context)
{
if (context.Request.Headers.ContainsKey("X-XSRF-TOKEN"))
{
_antiForgery.ValidateRequestAsync(context);
}
var tokens = _antiForgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions {
HttpOnly = false,
Secure = true
});
return _next(context);
}
我添加了 X-XSRF-TOKEN 的支票,以避免可能的问题,例如调用GET或OPTIONS飞行前检查时。
更新: 我的解决方案存在的问题是,如果您不将 X-XSRF-TOKEN 包含在HTTP请求标头中,则根本不会执行验证。我试图找到解决办法。