How to implement X-XSRF-TOKEN with angular2 app and net core app?

时间:2017-04-09 23:25:07

标签: c# angularjs angular asp.net-core

I have my net core app and antiforgery middlweare set up in Startup.cs:

        services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

in ConfigureServices method, and

        app.UseAntiForgeryMiddleware();

in Configure method.

Antiforgery middleware:

public class AntiForgeryMiddleware
    {
        private readonly IAntiforgery antiforgery;
        private readonly AntiforgeryOptions options;
        private readonly RequestDelegate next;

        public AntiForgeryMiddleware(RequestDelegate next, IAntiforgery antiforgery, IOptions<AntiforgeryOptions> options)
        {
            this.next = next;
            this.antiforgery = antiforgery;
            this.options = options.Value;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                if (string.Equals(context.Request.Path.Value, "/", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(context.Request.Path.Value, "/index.html", StringComparison.OrdinalIgnoreCase))
                {
                    // We can send the request token as a JavaScript-readable cookie, and Angular will use it by default.
                    var tokens = antiforgery.GetAndStoreTokens(context);
                    context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
                }

                if (string.Equals("POST", context.Request.Method, StringComparison.OrdinalIgnoreCase))
                {
                    await antiforgery.ValidateRequestAsync(context);

                    context.Response.StatusCode = 204;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            await next(context);
        }
    }

I use

[ValidateAntiForgeryToken]

on my controller action.

How do I set up angular2 post request to send x-xsrf-token header which will match net core app?

2 个答案:

答案 0 :(得分:1)

What you are talking about is inserting header x-xsrf-token into your request and send it to the backend.

You can accomplish that with modifying header options when you make http call:

Service

@Injectable
export class YourService {

    constructor(private http: Http) { }

    makeSomeRequst(data: any) {

        let headers = new Headers({ 'X-XSRF-TOKEN': yourTokenFromLocalStorage });
        let options = new RequestOptions({ headers: headers });

        this.http.post('url to your API call', data, options)
            .subscribe(result => {
                console.log('Your request was done and compliant to security on backend');
            }, err => {
                console.error('There was a problem with authentication');
                console.log(err)
            });
    }

}

With this, you will modify header and insert token to comply with your security mechanism. If you want to make that automated, you can follow this tutorial on how to create interceptor for http calls and insert token for all of them in one place, not to do it manually in every service:

You need to extend Angular's Http and provide new dependenices into your module. Follow the full tutorial here:

https://medium.com/aviabird/http-interceptor-angular2-way-e57dc2842462

答案 1 :(得分:1)

感谢Angular提供的CookieXSRFStrategy,Angular为您完成了这一部分。

对于Angular,您将使用其$ http服务发送AJAX请求。如果该服务可以找到标记值为XSRF-TOKEN的cookie作为令牌,则该服务将自动包含名称为X-XSRF-TOKEN的标头。

在.net端,您只需创建一些将获取请求令牌的中间件,并将其值存储为XSRF-TOKEN cookie(HttpOnly = false)。

验证过程:-

1)应用程序会将带有请求令牌的cookie XSRF-TOKEN和带有cookie令牌的另一个cookie .AspNetCore.Antiforgery。*发送回浏览器。

2)每当Angular发送Ajax请求时,请求都将包含带有请求令牌的标头X-XSRF-TOKEN和带有cookie令牌的cookie .AspNetCore.Antiforgery。*。

3)反伪造验证将确保两个令牌都有效并且共享相同的机密信息,等等。

由于请求令牌的默认标头名称为RequestVerificationToken,因此我们需要对其进行更改,并确保Antiforgery在名称为X-XSRF-TOKEN的标头中搜索请求令牌。让我们手动添加Antiforgery并在ConfigureServices方法中设置选项:

services.AddAntiforgery(opts => opts.HeaderName = "X-XSRF-Token");

现在,我们需要确保生成令牌并将请求令牌包含在名称为XSRF-TOKEN的cookie中,以便Angular $ http服务可以读取它并将其包含为标头。

这不能是仅HTTP的cookie,因为Angular代码需要读取cookie的值,以便可以将其作为标头包含在后续请求中!