Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
858 views
in Technique[技术] by (71.8m points)

asp.net web api - Anti forgery with token API and angular

I am working on Angular 6 application with SSO login and .net core web API. The code hits the back end on /token url first time which is a post operation. How do I do the anti forgery in this scenario. Please explain the flow of token transfer

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm not sure if that's what you're looking for, but I'll try to explain how I achieved it in a similar case.

First of all Angular has built in helpers for XSRF handling:

So the hardest part is to create custom XSRF middleware at api level.

I did it some time ago for one of my apps which was built with Angular 6 on the front and ASP.NET Core WebApi on the back-end.

Article which help me with it:

Your middleware could look like this:

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);
    }
}

Then as per mentioned article you have to add it to services in ConfigureServices method of Startup class:

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

And use it in Configure method:

app.UseAntiforgeryToken();

And of course to make use of it you have to decorate your api methods with [ValidateAntiForgeryToken] attribute.

Then in your Angular app you could create HttpInterceptor to send token only when it's needed.

@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());
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...