简体   繁体   中英

Configuring and Consuming Dotnet Core Web API in Angular 7

I created a dotnet core web api that I wish to consume in my angular 7 application. I ran into a few issues:

  1. I configured my middleware to use Jwt Authentication (see partial code below); however, I was receiving a 404 status code when I was expecting a 401. When an unauthorized user tried to access an authorized resource, the user was being redirected to a login page which did not exist. I stumbled on a post describing how to override applicationcookie to return a 401 instead of a 404. It partially fix my problem.
  2. When calling the API, I am getting a 401 but I have to add a cookie parameter to the request header.
  3. In my Angular application, I am able to get a token. However, any request to an authorize route in the API is returning a 404 because the header is missing the cookie parameter. I tried adding the cooking to the header, but I am getting the error message "http.js:1436 Refused to set unsafe header "cookie".

Jwt configuration

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddJwtBearer(options =>
   {
    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
  {
    ...
  };
});

overriding 404 to 401 instead.

// Configure the Application Cookie
services.ConfigureApplicationCookie(options => {
    // Override the default events
    options.Events = new CookieAuthenticationEvents
    {
        OnRedirectToAccessDenied = ReplaceRedirectorWithStatusCode(HttpStatusCode.Forbidden),
        OnRedirectToLogin = ReplaceRedirectorWithStatusCode(HttpStatusCode.Unauthorized)
    };

    // Configure our application cookie
    options.Cookie.Name = ".applicationname";
    options.Cookie.HttpOnly = true; // This must be true to prevent XSS
    options.Cookie.SameSite = SameSiteMode.None;
    options.Cookie.SecurePolicy = CookieSecurePolicy.None; // Should ideally be "Always"

    options.SlidingExpiration = true;
});

partial code for Angular interceptor - Based on a few comments, I removed the cookie and left the 'withcredential':'true' or 'included'. It did not make a difference. I hard coded the header values for now.

 intercept(request : HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<any>>{
    const headers = new HttpHeaders({
        'cookie':'ASPNET_COOKIE=CfDJ8K9C4yVY5HtDnXVGM_H-y2wweqlBcYiVLelvIMw2xntKY9j_AMP1GvLahXrR4fSNhbS3AysDXYVgFCrT_-LOyHT0iofBVwdllx3UHpXvbhXrCwSofHk5CwJn3Ae5dPI9gzx-BQSxIuwTQy-SF6LcYp9ctShzvQ5D6Qxty6OHuV5yGW8ShqQ05yV0qMdxivI87j6hv2eTdTW5oAqgYEN7LRUUA9MYz7Rq8i-XSB1KirtLC0v1i5NirYdENY2XNSpRF50A5lTu2m7M1CGe8TPU1mF2RW_rV7lOHAk-HYRCl80k8vYG8SVBYMrrK3soGApWcaDteZfJtN_K_g-xhZ2etT-js0ie0nCB_OWENrBilDpl8-0AcvjqvXG5E4AFXLh47XhAbRjkIOZECZn2WU_BT6TnvCkzUevgFZDMVVx6XmqUWzYb9WESlAoWfX4RYWnaDucba_FJDlMoi3YlXEaJgDnIB1-xYSKuuGScvAt7o49595pWLyFH4Yw7qgyOeLB5YpnookVPIEmyxj3-VXe5DU7mbW1GPFZMlcFXGU9P8RwkY0LO1OJiZP0wFh4NAQ_WSockhB8t_q0vM5jOBxcLNGTricbAZcEyYTwFa-XAKNgHXqu4q7LUCID02jZpNYbdj204CIV0I1H_kUN-e2AciA8QHFCx-gpq_6Tl-1t_vOaHW1sFfxHP2fvqu3r5hlVK2Q',
        'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoidXNlcnR3b0Bkc3NpbmMuY29tIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvZW1haWxhZGRyZXNzIjoidXNlcnR3b0Bkc3NpbmMuY29tIiwiZXhwIjoxNTQ0OTE0MDQxLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjIwMDEvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDoyMDAxLyJ9.WJhyQHGxjUykg5GXrcnm2vdadxmRF83iBwwRheddu8w',
        'Content-Type': 'application/json',
        'withCredentials' :'true'
      });
    console.log('modifying headers');
     const cloneRequest = request.clone({headers});
     return next.handle(cloneRequest)

CORS enable

  services.AddCors(options =>
            {
            options.AddPolicy("AllowSpecificOrigin",
                builder => builder
                .WithOrigins("http://localhost:4200")
                .AllowAnyHeader() // version important for cors.
                .AllowAnyMethod() //very import in order for cors to work
                    //.WithExposedHeaders("")
                    );
            });

I am hopping that someone would point out a different configuration for the API or a way to set the cookie in angular.

Updated

I've been able to narrow down the issue to the piece of code below. When I comment them out, I am getting the 401 when I tried to access an unauthorized resource.

    services.AddIdentity<IdentityUser, IdentityRole<string>>(options =>
    {
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequiredLength = 4;
        options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.Password.RequireUppercase = false;
        options.Password.RequiredUniqueChars = 1;

        options.User.RequireUniqueEmail = false;
        options.Lockout.AllowedForNewUsers = true;
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);

    }).AddEntityFrameworkStores<ClientPanelDbContext>()
    .AddDefaultTokenProviders();

It was my mistake, and I finally figured it out after much frustration. The API was working fine, and I was able to get a token and get access to protected resources. I mistakenly change the security key from config.Value.key to config.Value.Issuer. It was working before, so I never went back to that method. This morning, I noticed the message was that the signature was invalid. I went to the method that is creating the token, and I realize my mistakes. I fixed and I am getting 200, 401, 500, and 404 as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM