如何解决带有ValidAudiences的JWT TokenValidationParameters问题
我在带有Microsoft.AspNetCore.Identity的ASP.NET Core Web API(.NET Core 3.1)中使用JWT。 我有两个项目设置如下:
MyProj.Identity 和 MyProj.Server 。 我定义了2个角色:“管理员”和“用户”。我想使用角色“ user”中的用户授权MyProj.Identity生成的令牌对MyProj.Server控制器的调用。我还想授权角色为“ admin”的用户使用MyProj.Identity生成的令牌对MyProj.Identity进行某些调用。 在MyProj.Identity中,我具有以下控制器:
namespace MyProj.Identity.Controllers
{
[ApiController]
[Route("api/authentication")]
public class AuthenticationController : ControllerBase
{
//...
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginDto model)
{
//...
}
[Authorize(Roles = UserRoles.Admin)]
[HttpPost("register")]
public async Task<IActionResult> Register([FromBody] RegistrationInfo registrationInput)
{
//...
}
[Authorize(Roles = UserRoles.Admin)]
[HttpPost("register-admin")]
public async Task<IActionResult> Registeradmin([FromBody] RegistrationInfo registrationInput)
{
//...
}
}
}
在MyProj.Server中,有如下控制器:
namespace MyProj.Server.Controllers
{
[Authorize(Roles = UserRoles.User)]
[ApiController]
[Route("api/items")]
public class MyController : ControllerBase
{
//...
[HttpGet]
public async Task<ActionResult<IEnumerable<ItemDto>>> Get()
{
//...
}
//...
}
}
两个项目中的启动都具有以下配置
启动
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Adding Jwt Bearer
.AddJwtBearer(options =>
{
options.Savetoken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,ValidateAudience = true,ValidateIssuerSigningKey = true,Validissuer = Configuration["JWT:Validissuer"],ValidAudiences = Configuration.GetSection("JWT:ValidAudiences").Get<string[]>(),IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]))
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired","true");
}
return Task.CompletedTask;
}
};
});
//...
}
两个项目的appsettings.json中都有:
"JWT": {
"Validissuer": "http://MyProj.Identity.Url","ValidAudiences": [
"http://MyProj.Identity.Url","http://MyProj.Server.Url"
],"Secret": "MySecret","TokenExpiryMinutes": "120"
}
我遇到的问题是,当我在TokenValidationParameters中设置 ValidAudiences 属性时,登录时生成的令牌没有任何“ aud”设置(使用{{ 3}}),因此授权失败。如果我改为设置 ValidAudience 属性(单个受众),则一切正常,但是我不能授权多个受众。我也尝试从列表中手动设置“ ValidAudiences”属性(而不是从配置中设置),但是结果是相同的。对于多个有效受众群体,我似乎缺少一些东西。任何想法将不胜感激。
解决方法
解决方案就在我眼前:)。
MyProj.Identity中的Login方法(生成令牌)需要包括针对每个受众的身份验证声明,如下所示:
namespace MyProj.Identity.Controllers
{
[ApiController]
[Route("api/authentication")]
public class AuthenticationController : ControllerBase
{
// ...
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginDto model)
{
// ...
foreach (var audience in _configuration.GetSection("JWT:ValidAudiences").Get<string[]>())
{
authClaims.Add(new Claim(JwtRegisteredClaimNames.Aud,audience));
}
// ...
var token = new JwtSecurityToken(
issuer: _configuration["JWT:ValidIssuer"],expires: DateTime.Now.AddMinutes(int.Parse(_configuration["JWT:TokenExpiryMinutes"])),claims: authClaims,signingCredentials: new SigningCredentials(authSigningKey,SecurityAlgorithms.HmacSha256));
}
// ...
}
}
这解决了问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。