微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有ValidAudiences的JWT TokenValidationParameters问题

如何解决带有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 举报,一经查实,本站将立刻删除。