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的主要内容,如果未能解决你的问题,请参考以下文章