AspNet WebApi核心JWT令牌未通过身份验证

时间:2020-10-04 11:09:01

标签: c# asp.net-core asp.net-identity

我正在构建一个api,但无法获得授权。

我已经删除了Authorize属性,并验证了端点可以正常工作。

我的ConfigureServices方法

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        services.AddDbContext<SomeContext>(options =>
        {
            var connectionString = Configuration.GetConnectionString("default");
            Console.WriteLine(connectionString);
            options.UseSqlServer(connectionString);
        });
        services.AddDefaultIdentity<IdentityUser>()
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<SomeContext>()
            .AddDefaultTokenProviders();

        services.Configure<IdentityOptions>(options =>
        {
            options.Password.RequireDigit = true;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireUppercase = false;
            options.Password.RequiredLength = 6;

            options.User.RequireUniqueEmail = false;
        });

        services.AddAuthorization(options =>
        {
            options.AddPolicy(Roles.Manager, policy=> policy.RequireClaim(Roles.Manager));
            options.AddPolicy(Roles.Admin, policy=> policy.RequireClaim(Roles.Admin));
        });


        // add other services here
  }

My Configure method:


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();
        app.UseAuthentication();
        
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });


    }

和我的令牌:

    [HttpPost]
    public async Task<ActionResult<string>> Login(User user)
    {
        var identityUser = await _userManager.FindByNameAsync(user.Username);
        var canSignIn = await _signInManager.CanSignInAsync(identityUser);

        if (!canSignIn) return Unauthorized();

        var signResult = await _signInManager.CheckPasswordSignInAsync(identityUser, user.Password, false);
        if (!signResult.Succeeded) return Unauthorized();

        var userRoles = await _userManager.GetRolesAsync(identityUser);
        var claims = (await _userManager.GetClaimsAsync(identityUser)).ToList();

        claims.AddRange(userRoles.Select(x=> new Claim(ClaimTypes.Role, x)));

        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(ConstantsToAddToSecrets.Seceret));
        var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
        var jwtToken = new JwtSecurityToken
        (
        ConstantsToAddToSecrets.Issuer,
        ConstantsToAddToSecrets.Audience,
        claims,
        DateTime.Now,
        DateTime.Now.AddDays(1),
        signingCredentials
        );

       

        return Ok(
            new {access_token = new JwtSecurityTokenHandler().WriteToken(jwtToken)}
            );
    }

最后是我的基本控制器:

[Authorize]
[Route("api/test")]
public class TestController:Controller
{
    [HttpGet]
    public string Get()
    {
        return "IWorked";
    }
}

现在我要问的问题是,当我在类似bearer my-token-here的邮递员头中发送不记名令牌时,它会检查不记名令牌,以及为什么我在添加{{ 1}}属性分配给控制器?

更新 我更改了以下代码:(并从获取404变为现在的401)

[Authorize]

2 个答案:

答案 0 :(得分:0)

它似乎您尚未向授权流程中添加任何JWT处理中间件。使用Azure AD,这对我有用:

            var azureAd = Configuration.GetSection("AzureAd");

            services.AddAuthorization(options =>
            {
                options.DefaultPolicy =
                    new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
                    .RequireAuthenticatedUser()
                    .Build();
            });

            services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme)
                .AddJwtBearer(x =>
                {
                    x.Audience = azureAd.GetValue<string>("ClientId");
                    x.Authority = $"{azureAd.GetValue<string>("Instance")}/{azureAd.GetValue<string>("TenantId")}/v2.0";
                    x.RequireHttpsMetadata = false;
                    x.SaveToken = true;
                    x.TokenValidationParameters = new TokenValidationParameters
                    {
                        AudienceValidator = null,
                        ValidateIssuerSigningKey = true,
                        ValidateIssuer = true,
                        ValidateActor = true,
                        ValidateLifetime = true,
                        ValidateTokenReplay = true,
                        ValidateAudience = true
                    };
                });

答案 1 :(得分:0)

对于遇到此问题的其他人,我找到了解决方法Here On YouTube

他在他的博客Here

最终结果是:

        services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Constants.ConstantsToAddToSecrets.Seceret));
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = securityKey,
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });

在创建令牌以使用tokenHandler

公共异步任务AuthenticateAsync(LoginModel loginModel) { var signatureInUser =等待SigninAsync(loginModel); 如果(signedInUser == null)返回null;

        var claims = (await _userManager.GetClaimsAsync(signedInUser)).ToList();
        var userRoles = await GetRolesAsync(signedInUser);

        claims.AddRange(userRoles);

        var tokenHandler = new JwtSecurityTokenHandler();
        var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Constants.ConstantsToAddToSecrets.Seceret));
        var tokenDescriptor = new SecurityTokenDescriptor()
        {
            Subject = new ClaimsIdentity(claims.ToArray()), 
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = new SigningCredentials(
                securityKey, 
                SecurityAlgorithms.HmacSha256Signature
                ),
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }