[JWT] TokenValidationParameters RoleClaimType Not Fully Respected
See original GitHub issueOriginal issue: https://github.com/aspnet/AspNetCore/issues/11789
Describe the bug
After passing value to RoleClaimType. It can no longer pass Authorize(Roles="")
.
To Reproduce
Steps to reproduce the behavior:
- Using this version of ASP.NET Core ‘2.2’
- Run this code
Startup.cs
// Inject token service
services.AddScoped<ITokenService, TokenService>();
// Inject appsettings.json
var tokenConfigs = Configuration.GetSection("tokenManagement");
services.Configure<TokenConfigs>(tokenConfigs);
// JWT authorization setup
var token = tokenConfigs.Get<TokenConfigs>();
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateLifetime = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(token.Secret)),
ValidIssuer = token.Issuer,
ValidAudience = token.Audience,
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Roles, // <---- Overriding, new value "role"
};
});
TokenService.cs
public class TokenService : ITokenService
{
private TokenConfigs _tokenManagement;
public TokenService(IOptions<TokenConfigs> tokenManagement)
{
_tokenManagement = tokenManagement.Value;
}
public string GetAuthToken(TokenRequest req)
{
var claims = new[]
{
new Claim(JwtClaimTypes.Name, req.UserName),
new Claim(JwtClaimTypes.Role, "xxxx"), // <----- Custom type
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenManagement.Secret));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwtToken = new JwtSecurityToken(
claims: claims,
issuer: _tokenManagement.Issuer,
audience: _tokenManagement.Audience,
expires: DateTime.Now.Date.AddDays(1),
signingCredentials: credentials
);
var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
return token;
}
}
AuthController.cs
[AllowAnonymous]
[HttpPost]
public async Task<ActionResult<string>> Post([FromBody] TokenRequest req)
{
string token = null;
if (isValidUser)
{
token = _tokenService.GetAuthToken(req);
}
return Ok(token); // <--- Correct result returned
}
[HttpGet]
[Authorize(Roles = "admin,xxxx")] <------ Fail
public ActionResult<string> Get()
{
var name = User.Identity.Name;
var isAdmin = User.IsInRole("admin");
var isXXXX = User.IsInRole("xxxx"); <---- False
return Ok($"{name} {isAdmin} {isXXXX}");
}
-
With these arguments ‘…’ N/A
-
See error Fail to authorize. User.Claims contains incorrect claim type.
{http://schemas.microsoft.com/ws/2008/06/identity/claims/role: xxxx}
Expected behavior
Able to pass authorization. Claims should respect what’s passed in.
Screenshots
N/A
Additional context
Add any other context about the problem here.
Include the output of dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 2.2.204
Commit: 8757db13ec
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17134
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\2.2.204\
Host (useful for support):
Version: 2.2.5
Commit: 0a3c9209c0
.NET Core SDKs installed:
2.1.201 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.400 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.402 [C:\Program Files\dotnet\sdk]
2.1.403 [C:\Program Files\dotnet\sdk]
2.1.500 [C:\Program Files\dotnet\sdk]
2.1.502 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.504 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
2.1.602 [C:\Program Files\dotnet\sdk]
2.1.604 [C:\Program Files\dotnet\sdk]
2.1.700 [C:\Program Files\dotnet\sdk]
2.2.204 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.3-servicing-26724-03 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Issue Analytics
- State:
- Created 4 years ago
- Comments:10 (5 by maintainers)
Top Results From Across the Web
Value set for TokenValidationParameters.RoleClaimType ...
Value set for TokenValidationParameters.RoleClaimType converts string to PascalCase causing JWT to be invalidated.
Read more >Problems when adding Azure AD Authentication and ...
When using Admin->Access Rights->Set Access Rights can I not see the roles ... TokenValidationParameters = new TokenValidationParameters
Read more >Acces Token With .Net Core Api
Hello to all. I'm working with .net core 2.0 web api and web application. My web application has been configured to login/logut using...
Read more >User Roles - Microsoft Q&A
When I try to access the role using the following code [user.IsInRole("Admin")] , it does not seem to recognize the "Admin" role. I...
Read more >Architecting-Cloud-Native-NET-Apps-for-Azure.pdf
This guide begins by defining cloud native and introducing a reference application built using cloud- native principles and technologies.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Thanks @GeoK , it works. Though I still found there is a bit inconsistency, since without your codes, the “name” claim type won’t be mapped into internal claim type, only “role” claim type gets mapped.
Also I’m curious about the syntax you used,
x.SecurityTokenValidators.FirstOrDefault() is JwtSecurityTokenHandler
did a boolean check, then you can still assign theFirstOrDefault
result tojwtSecurityTokenHandler
? It works, but feels like magic, is this some new C# syntax sugar?Hi @clauzf - the issue here is the JwtSecurityTokenHandler performs inbound ‘type’ mapping.
You can disable the mapping on the application level:
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
or per instance (assuming that you are using default SecurityTokenValidator(s)):