Asp.Net core Authorization with Bearer token status Unauthorized 401 with Valid token

Posted

技术标签:

【中文标题】Asp.Net core Authorization with Bearer token status Unauthorized 401 with Valid token【英文标题】: 【发布时间】:2020-08-15 16:28:06 【问题描述】:
    public class User: IdentityUser
    
        // ... code here
    


    [HttpPost]
    [Route("Login")]
    //POST: /api/User/Login
    public async Task<IActionResult> Login(LoginModel model)
    
        var user = await _UserManager.FindByEmailAsync(model.Email);
        if (user != null && await _UserManager.CheckPasswordAsync(user, model.Password))
        
            var tokenDescriptor = new SecurityTokenDescriptor
            
                Subject = new ClaimsIdentity(
                    new Claim[]
                    
                      new Claim("UserID", user.Id.ToString())
                    ),
                Expires = DateTime.UtcNow.AddDays(5),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_ApplicationSettings.JWT_Secret)), SecurityAlgorithms.HmacSha256Signature)
            ;
            var tokenHandler = new JwtSecurityTokenHandler();
            var securityToken = tokenHandler.CreateToken(tokenDescriptor);
            var token = tokenHandler.WriteToken(securityToken);
            return Ok(new  token );
        
        else
        
            return BadRequest(new  message = "Username or password is incorrect" );
        
    

    [HttpGet]
    [Authorize]
    //GET: /api/UserProfile
    public async Task<Object> GetUserProfile()
    
        var t = User.Claims.Count();

        string userId = User.Claims.First(c => c.Type == "UserID").Value;
        var user = await _UserManager.FindByIdAsync(userId);
        return new
        
            user.FirstName,
            user.LastName,
            user.Email,
            user.ProfileType
        ;
    

当我尝试使用返回的令牌(使用邮递员)获取连接的用户时,我总是得到状态 401 Unathorized。 此外,我发现 User.Claims.Count() 为 0(我通过评论来查看 [Authorize] 出了什么问题)。

有谁知道问题出在哪里?

谢谢!

编辑:应用配置

    public void ConfigureServices(IServiceCollection services)
    
        //Inject AppSettings
        services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));

        services.AddControllers();
        services.AddDbContext<AuthentificationContext>(
           options =>
           
               options.Usemysql(Configuration.GetConnectionString("IdentityConnection"));
           );

        services.AddDefaultIdentity<User>()
                .AddEntityFrameworkStores<AuthentificationContext>();

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

        services.AddCors();

        //jwt authentification
        var key = Encoding.UTF8.GetBytes(Configuration["ApplicationSettings:JWT_Secret"].ToString());
        services.AddAuthentication(x =>
        
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        ).AddJwtBearer(x =>
       
           x.RequireHttpsMetadata = false;
           x.SaveToken = false;
           x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
           
               ValidateIssuerSigningKey = true,
               IssuerSigningKey = new SymmetricSecurityKey(key),
               ValidateIssuer = false,
               ValidateAudience = false,
               ClockSkew = TimeSpan.Zero
           ;
       );

        services.Configure<CookiePolicyOptions>(options =>
        
            services.AddHttpContextAccessor();
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        );
    

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    
        app.Use(async (ctx, next) =>
        
            await next();
            if (ctx.Response.StatusCode == 204)
            
                ctx.Response.ContentLength = 0;
            
        );

        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();
        

        app.UseCors(options =>
            options.WithOrigins(Configuration["ApplicationSettings:Client_URL"].ToString())
                   .AllowAnyMethod()
                   .AllowAnyHeader());

        app.UseRouting();

        app.UseAuthorization();

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

        app.UseAuthentication();
    

【问题讨论】:

ConfigureServicesConfigure 方法中显示您的授权配置。 我使用 ConfigureServices 和 Configure 方法编辑了帖子。谢谢 1.将app.UseAuthentication(); 放在app.UseAuthorization(); 之前 2. 在GetUserProfile 方法上使用[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] 而不是[Authorize] 来触发JWT 承载认证。 它工作正常。非常感谢! 【参考方案1】:

你应该注意将app.UseAuthentication();放在app.UseAuthorization();之前的中间件顺序

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

【讨论】:

以上是关于Asp.Net core Authorization with Bearer token status Unauthorized 401 with Valid token的主要内容,如果未能解决你的问题,请参考以下文章

Asp.Net core (Full .Net framework) vs Asp.Net core (.Net Core) 性能

Asp.NET Core进阶 第四篇 Asp.Net Core Blazor框架

.NET Core 1.0ASP.NET Core 1.0和EF Core 1.0简介

asp.net core 注入后仍然报错?

深入研究 Mini ASP.NET Core(迷你 ASP.NET Core),看看 ASP.NET Core 内部到底是如何运行的

.Net Core 学习 - ASP.NET Core 概念学习