设置了JWT令牌和策略后,我将获得未经授权的401

时间:2020-04-23 23:56:56

标签: asp.net-core asp.net-core-3.1 jwt-auth

我点击下面的教程链接。

https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login

我试图了解它的工作原理,并且想使用使用此令牌的基于角色的身份验证。因此,我在Startup.cs文件中制定了另一个策略,如下所示。

我尝试像使用[Authorize(Policy = "admin")]控制器一样使用它,但是每次尝试使用unauthenticated都得到postman时。 我想念什么?如何基于教程进行基于角色的身份验证?

配置

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

        var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));

        // Configure JwtIssuerOptions
        services.Configure<JwtIssuerOptions>(options =>
        {
            options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
            options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
            options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
        });
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],

            ValidateAudience = true,
            ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],

            ValidateIssuerSigningKey = true,
            IssuerSigningKey = _signingKey,

            RequireExpirationTime = false,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero
        };

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(configureOptions =>
        {
            configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
            configureOptions.TokenValidationParameters = tokenValidationParameters;
            configureOptions.SaveToken = true;
        });

        // api user claim policy
        services.AddAuthorization(options =>
        {
            options.AddPolicy("ApiUser", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, Constants.Strings.JwtClaims.ApiAccess));
        });
        services.AddAuthorization(options =>
            options.AddPolicy("admin", policy => policy.RequireRole("admin"))
        );
        var builder = services.AddIdentityCore<AppUser>(o =>
        {
            // configure identity options
            o.Password.RequireDigit = false;
            o.Password.RequireLowercase = false;
            o.Password.RequireUppercase = false;
            o.Password.RequireNonAlphanumeric = false;
            o.Password.RequiredLength = 6;
        });
        builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services);
        builder.AddEntityFrameworkStores<CDSPORTALContext>().AddDefaultTokenProviders().AddRoles<IdentityRole>(); 
        //.AddRoles<IdentityRole>()
        services.AddControllers();
        services.AddAutoMapper(typeof(Startup));
        services.AddSingleton<IJwtFactory, JwtFactory>();
        services.TryAddTransient<IHttpContextAccessor, HttpContextAccessor>(); 

        services.AddScoped<IRegionRepository, RegionRepository>();
        services.AddScoped<IRegionService, RegionService>();
        services.AddScoped<IEmailHelper, EmailHelper>();

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseCors("CorsPolicy");
        app.UseExceptionHandler(
                builder =>
                {
                    builder.Run(
                      async context =>
                      {
                          context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                          context.Response.Headers.Add("Access-Control-Allow-Origin", "*");

                          var error = context.Features.Get<IExceptionHandlerFeature>();
                          if (error != null)
                          {
                              context.Response.AddApplicationError(error.Error.Message);
                              await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false);
                          }
                      });
                });


        app.UseRouting();
        app.UseStaticFiles();
        app.UseAuthentication();
        app.UseAuthorization();


        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();

        });

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "Client";
            spa.UseAngularCliServer(npmScript: "start");
        });


    }
}

身份验证控制器

// POST api/auth/login
[HttpPost("login")]
public async Task<IActionResult> Post([FromBody]CredentialsViewModel credentials)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var identity = await GetClaimsIdentity(credentials.UserName, credentials.Password);



    if (identity == null)
    {
        //return null;
        return BadRequest(Error.AddErrorToModelState("login_failure", "Invalid username or password.", ModelState));
    }
    var id = identity.Claims.Single(c => c.Type == "id").Value; 
    var user = await _userManager.FindByIdAsync(id);
    IList<string> role = await _userManager.GetRolesAsync(user);
    var jwt = await Tokens.GenerateJwt(identity, role[0], _jwtFactory, credentials.UserName, _jwtOptions, new JsonSerializerSettings { Formatting = Formatting.Indented });


    return new OkObjectResult(jwt);

}

我尝试了所有方法,但没有一个起作用

[Authorize(Policy = "ApiUser")]
[HttpGet("getPolicy")]
public string GetPolicy()
{
    return "policyWorking";
}
[Authorize(Roles = "admin")]
[HttpGet("getAdmin")]
public string GetAdmin()
{
    return "adminWorking";
}
[Authorize ]
[HttpGet("getAuthorize")]
public string GetAuthorize()
{
    return "normal authorize Working";
}

解码令牌

  "jti": "840d507d-b2d0-454b-bd1f-007890d3e669",
  "iat": 1587699300,
  "rol": "api_access",
  "id": "1ac370e2-f5e9-4404-b017-8a3c087e2196",
  "nbf": 1587699299,
  "exp": 1587706499

1 个答案:

答案 0 :(得分:0)

我忘记将此添加到appsetting中。

  "JwtIssuerOptions": {
    "Issuer": "webApi",
    "Audience": "http://localhost:4200/"
  }