Arsiwaldi
Arsiwaldi

Reputation: 523

Angular 4 with ASP.NET Core 2.0 is giving back 401 error on JWT (CORS)

I´ve written front-end application in Angular 4. This front-end is trying to make a request to endpoints which required authorization token. I am using JWT token with ASP.NET Core 2.0. Because both are running on different ports, i have to set CORS.

So request with added Authorization header returns response from server with 401 Error code. I tried to use many solution from these threads:

  1. Setting cors there is also idea with custom CorsMiddleware,
    which I Tried, but still receiving 401.
  2. Similiar solution to custom Cors middleware
  3. Custom cors middleware This wasn´t even working


, which at first glance appear to be solving a similar problem. However, I am not able to get right response from server. Method without attribute [Authorize] are working correctly (Methods which don´t need Bearer token) Could be error somewhere else? (Token are indeed valid, tested from POSTMAN). Have anybody idea, what's could be a problem?


This is how I set CORS

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.WithOrigins("http://localhost:4200")
                .AllowAnyMethod()
                .AllowAnyHeader());
    });
}

Apply Cors before Mvc

public void Configure(IApplicationBuilder app,
IHostingEnvironment env, UnitOfWork identityCustomDbContext)
{

    app.UseCors("CorsPolicy");
    app.UseMvc();

}


Angular token interceptor

export class TokenInterceptor implements HttpInterceptor {
    constructor(private injector: Injector, private _router: Router){}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
        const auth = this.injector.get(AuthService);
        let token = auth.getToken();
        if(token){
                const authReq = req.clone({headers:req.headers.set('Authorization', token).set('Content-Type','application/json')})
                return next.handle(authReq);
        }
    }
}

Requests headers


OPTIONS request
status code: 204 No Content

OPTIONS http://localhost:57498/api/users
Host: localhost:57498
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization,content-type
Origin: http://localhost:4200
Connection: keep-alive

OPTIONS response

Server: Kestrel
Access-Control-Allow-Headers: authorization,content-type
Access-Control-Allow-Origin: http://localhost:4200
X-SourceFiles: =?UTF-8?B?RDpcQ29uZmVlLWJhY2tlbmRcQ29uZmVlLXdlYkFwaVxDb25mZWUtd2ViQXBpXGFwaVx1c2Vycw==?=
X-Powered-By: ASP.NET

GET request
status code: 401 Unauthorized

Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:4200/admin/conferences
Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsdUBzLmNvbSIsImp0aSI6ImJmMDk3ZmYwLTRjMGUtNGZkMC04YTM1LTQ4MzZlY2U2OGE0OSIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWVpZGVudGlmaWVyIjoiYmMzZWQxMzQtMTAyNS00OWVjLTk1YWYtZDk0ODMxNWVmYzI0IiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQWRtaW5pc3RyYXRvciIsImV4cCI6MTUyMDUzNzQ3MCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1NzQ5OC8iLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjU3NDk4LyJ9.rUwoq_olnVg7lOvtX1AIpB1JDDwBi9ra3FhBLaSSLuQ
Content-Type: application/json
Origin: http://localhost:4200
Connection: keep-alive

GET response

Server: Kestrel
WWW-Authenticate: Bearer
Access-Control-Allow-Origin: http://localhost:4200
X-SourceFiles: =?UTF-8?B?RDpcQ29uZmVlLWJhY2tlbmRcQ29uZmVlLXdlYkFwaVxDb25mZWUtd2ViQXBpXGFwaVx1c2Vycw==?=
X-Powered-By: ASP.NET
Content-Length: 0


According to link 2 and 3 above, I tried to implement custom CORS middleware

public class CorsMiddleware
{
    private readonly RequestDelegate _next;

    public CorsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
        httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
        return _next(httpContext);
    }
}
public static class CorsMiddlewareExtensions
{
    public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CorsMiddleware>();
    }
}
public void Configure(IApplicationBuilder app,
IHostingEnvironment env, UnitOfWork identityCustomDbContext)
{
app.UseCorseMiddleware();
app.UseMvc();
app.UseCors("CorsPolicy");
}

The result was same. I have recieved 401 from server.

Upvotes: 0

Views: 1604

Answers (1)

R. Richards
R. Richards

Reputation: 25161

Posting my comment as an answer.

You are passing a token to the service, but you are not including the word bearer before the token string, so the service has no clue what to do with it, thus the 401 Unauthorized.

Easy enough to miss. Postman handles this for you, so you may not think about it with Angular.

Upvotes: 2

Related Questions