asp.net 核心中的 jwt 令牌无效

Posted

技术标签:

【中文标题】asp.net 核心中的 jwt 令牌无效【英文标题】:Invalid jwt Token in asp.net core 【发布时间】:2020-11-19 19:09:06 【问题描述】:

我正在尝试在我的 Angular 应用程序和 ASP.net 核心中使用 JWT。对于初学者,我使用“邮递员”来测试我的端点。 在我的 API 中,这是我设置 JWT 的方式

launchsettings.json


  "iisSettings": 
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": 
      "applicationUrl": "http://localhost:22468",
      "sslPort": 0
    
  ,
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": 
    "IIS Express": 
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      ,
      "ancmHostingModel": "InProcess"
    ,
    "autosweeprfid_api": 
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      ,
      "applicationUrl": "http://localhost:5000"
    
  

appsettings.json

"Jwt": 
    "SecretKey": "KqcL7s998JrfFHRP1",
    "Issuer": "http://localhost:22468",
    "Audience": "http://localhost:4201"
  

startup.cs => ConfigureServices

 // Get the Validators in appsettings
            var validIssuer = Configuration["Jwt:Issuer"];
            var validAudience = Configuration["Jwt:Audience"];

            services.AddAuthentication(options =>
            
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            )
               .AddJwtBearer(options =>
               
                   options.TokenValidationParameters = new TokenValidationParameters
                   
                       ValidateIssuer = true,
                       ValidateAudience = false,
                       ValidateLifetime = true,
                       ValidateIssuerSigningKey = true,

                       ValidIssuer = validIssuer,
                       ValidAudience = validAudience,
                       IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]))

                   ;
               );

启动 => 配置

 app.UseCors("MyPolicy");

            // Make the "PrivateImages" forlder servable
            app.UseStaticFiles();
            app.UseStaticFiles(new StaticFileOptions()
            
                FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"PrivateImages")),
                RequestPath = new PathString("/PrivateImages")
            );

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            
                endpoints.MapControllers();
                endpoints.MapHub<MessageHub>("/MessageHub");
            );

授权控制器

[HttpPost, Route("login")]
        public IActionResult Login([FromBody] LoginModelDto model)
        
            IActionResult response = Unauthorized();

            User user = context.Users.SingleOrDefault(x => x.UserName == model.UserName);

            if (user == null) return response;
            if (!user.IsActive) return response;

            var decryptedPassword = Decryption.Decrypt(user.Password, user.SaltValue);
            if (decryptedPassword == model.Password)
            
                var roles = (from a in context.UserRoles
                             join b in context.Roles on a.RoleId equals b.Id into ab
                             from x in ab.DefaultIfEmpty()
                             where a.UserId == user.Id
                             select new Role
                             
                                 RoleName = x.RoleName,
                             ).ToList();

                var claims = new List<Claim>
                
                    new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Sub, user.UserName),
                    new Claim("UserId", user.Id.ToString()),
                    new Claim("FirstName", user.FirstName.ToString()),
                    new Claim("MiddleName", user.MiddleName.ToString()),
                    new Claim("LastName", user.LastName.ToString()),
                    new Claim("EmailAddress", user.EmailAddress.ToString()),
                    new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
                ;

                foreach (var role in roles)
                
                    //claims.Add(new Claim(ClaimTypes.Role, role.RoleName));
                    claims.Add(new Claim("role", role.RoleName));
                

                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

                var tokeOptions = new JwtSecurityToken(
                        issuer: "http://localhost:22468",
                        audience: "http://localhost:4201",
                        claims: claims,
                        expires: DateTime.Now.AddMinutes(30),
                        signingCredentials: signinCredentials
                    );
                var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);

                user.Online = true;
                context.SaveChanges();

                return Ok(new  Token = tokenString );
            
            else
            
                return response;
            
        

我可以正常登录,但是当我尝试使用具有 [Authorize] 属性的方法时,Postman 给了我一个 401。

【问题讨论】:

@marc_s,我也这样做了,先生,我仍然得到相同的结果 【参考方案1】:

我明白了。所有代码都是正确的。我只是错过了使用“身份验证”本身。所以我只是将app.UseAuthentication(); 放在app.UseRouting();app.UseAuthorization(); 之间,结果很好。谢谢。

【讨论】:

【参考方案2】:

您刚刚在管道内配置了authorization。您还需要配置authentication。请记住,它必须在管道内部授权之前完成。顺序很重要,因为首先我们需要验证用户是谁,然后我们需要检查他/她拥有哪些权限。

app.UseRouting();

app.UseAuthentication(); //Authentication

app.UseAuthorization(); //Authorization

【讨论】:

我已经打败了你!哈哈哈!但这正是正确的答案。谢谢。 很高兴您也能弄清楚。

以上是关于asp.net 核心中的 jwt 令牌无效的主要内容,如果未能解决你的问题,请参考以下文章

我们可以在 Asp.NET Core 中销毁/无效 JWT 令牌吗?

Asp.net 核心中的会话和应用程序变量,以防我们使用 JWT 令牌(因此没有基于 cookie 的会话)

控制器 ASP.net 核心 2.1 中的 Jwt 角色身份验证

asp.net 核心身份 - 2 种类型的 jwt 令牌

通过 Auth0 React 和 ASP.net 核心授权然后使用 JWT 令牌

使用 JWT 令牌保护 asp.net 核心 Web api 时如何从 Azure AD 获取用户