JWT 令牌未被正确验证
JWT token not being validated correctly
我有一个 ASP.NET 使用 JWT 进行验证的核心 MVC 应用程序
我在启动程序中添加身份验证 class,使用我们的应用程序设置文件中的令牌密码来验证令牌。
services.Configure<ApplicationSettings>(Configuration.GetSection("AppSettings"));
var key = System.Text.Encoding.UTF8
.GetBytes(Configuration.GetSection("AppSettings:Token").Value);
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 TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
并添加授权中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors("MyPolicy");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
现在,当用户尝试登录以下控制器时,方法是 运行,使用相同的令牌密码生成令牌。
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] UserForLoginDto userForLoginDto)
{
var user = await _userManager.FindByNameAsync(userForLoginDto.Username);
var result = await _signInManager
.CheckPasswordSignInAsync(user, userForLoginDto.Password, false);
if (result.Succeeded)
{
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("UserID",user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8
.GetBytes(appSettings.Token)), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(securityToken);
return Ok(new { token });
}
return Unauthorized();
}
所以当用户登录时,生成一个令牌并发送回客户端。
此时我希望我可以将 [Authorize]
属性添加到控制器方法,然后 MVC 框架将在 http headers 中查找有效令牌。所以我创建了一个测试控制器方法
[HttpGet]
[Authorize]
public IActionResult Get()
{
return Ok("Test");
}
并发送与授权 header 设置为 Bearer <Token>
的测试控制器方法相对应的请求,但我仍然收到 401 未经授权。
谁能解释为什么会发生这种情况?如果您需要更多信息,请告诉我。
我认为是使用你的中间件的问题:
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
可以通过以下方式尝试:
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
因此,首先,我们使用对用户进行身份验证 - 中间件读取令牌并将身份注入 http 上下文
我有一个 ASP.NET 使用 JWT 进行验证的核心 MVC 应用程序
我在启动程序中添加身份验证 class,使用我们的应用程序设置文件中的令牌密码来验证令牌。
services.Configure<ApplicationSettings>(Configuration.GetSection("AppSettings"));
var key = System.Text.Encoding.UTF8
.GetBytes(Configuration.GetSection("AppSettings:Token").Value);
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 TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
});
并添加授权中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors("MyPolicy");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
现在,当用户尝试登录以下控制器时,方法是 运行,使用相同的令牌密码生成令牌。
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] UserForLoginDto userForLoginDto)
{
var user = await _userManager.FindByNameAsync(userForLoginDto.Username);
var result = await _signInManager
.CheckPasswordSignInAsync(user, userForLoginDto.Password, false);
if (result.Succeeded)
{
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("UserID",user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8
.GetBytes(appSettings.Token)), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(securityToken);
return Ok(new { token });
}
return Unauthorized();
}
所以当用户登录时,生成一个令牌并发送回客户端。
此时我希望我可以将 [Authorize]
属性添加到控制器方法,然后 MVC 框架将在 http headers 中查找有效令牌。所以我创建了一个测试控制器方法
[HttpGet]
[Authorize]
public IActionResult Get()
{
return Ok("Test");
}
并发送与授权 header 设置为 Bearer <Token>
的测试控制器方法相对应的请求,但我仍然收到 401 未经授权。
谁能解释为什么会发生这种情况?如果您需要更多信息,请告诉我。
我认为是使用你的中间件的问题:
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
可以通过以下方式尝试:
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
因此,首先,我们使用对用户进行身份验证 - 中间件读取令牌并将身份注入 http 上下文