使用令牌API和角度的防伪

时间:2018-10-31 15:04:23

标签: angular asp.net-web-api asp.net-core-webapi antiforgerytoken

我正在使用SSO登录和.net核心Web API开发Angular 6应用程序。该代码首次在/ token网址上到达后端,这是一项后期操作。在这种情况下,我该如何做防伪。请说明令牌转移的流程

2 个答案:

答案 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)

这个问题很旧,但是我的解决方案可以帮助某人。对我们有用的东西:

    使用Angular FE端上的
  • HttpXsrfTokenInterceptor ,它设置了 X-XSRF-TOKEN 标头。当然,cookie必须在 XSRF-TOKEN

    下包含令牌
  • .net核心方面的
  • :基本上是上述方法,使用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请求标头中,则根本不会执行验证。我试图找到解决办法。