You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using AddOpenIdConnect, the middleware is not properly parsing the access token's JWT Token Claims from OIDC Providers.
Specifically, I am testing this out with Keycloak, but I imagine this is similar with other providers too.
When using the .AddOpenIdConnect as an Authentication source, the integration works, however, once the access token is returned from the provider, the access token is not being properly parsed. It is able to parse some of the fields from the access token, but not others. Especially roles. For example, if the token is:
The resulting User in ASP.NET would only have the preferred_username name set. Some of the other fields were getting processed and put into the Claims object, like exp, iat, jti, sub, and sid (maybe some others) but many are missing. In the debugger, I only had 8 total Claims on the user. The user was missing a lot of the more detailed fields like roles, name, email, family_name, etc.
This made it impossible to lock down routes using [Authorize(Roles = "Admin")], as none of the user's roles were getting populated into their Claims, even if you set the options.TokenValidationParameters.RoleClaimType = "roles", it would not properly parse out the user's roles.
As a workaround for this, I had to add a custom event listener to the OnTokenValidated event and manually parsed out the Users roles and append them to the User's Identity:
options.Events.OnTokenValidated =async ctx =>{// For some reason, the access token's claims are not getting added to the user in C#// So this method hooks into the TokenValidation and adds it manually...// This definitely seems like a bug to me.// First, let's just get the access token and read it as a JWTvartoken= ctx.TokenEndpointResponse.AccessToken;varhandler=new JwtSecurityTokenHandler();varparsedJwt= handler.ReadJwtToken(token);// Once parsed, any `role` claims is just being set to the text "role" for the claim type.// But Microsoft requires using their enum, `ClaimTypes.Role` if you want to use the claims with the `[Authorize(Roles = "...")]` Annotation.// So, we need to convert any "role" claims in the JWT to the actual Microsoft enum for them to be properly picked up...// So convert them here...varupdatedClaims= parsedJwt.Claims.ToList().Select(c =>{return c.Type =="role"?new Claim(ClaimTypes.Role, c.Value):c;});// Finally, use the new claims list that we grabbed from the JWT and add them as a new `Identity` that contains them. ctx.Principal.AddIdentity(new ClaimsIdentity(updatedClaims));};
I am VERY certain that this is a bug with the Microsoft Authentication library, and this workaround should not be required from my understanding. See also this StackOverflow question
Expected Behavior
Expected the Token to be properly parsed without needing to add a custom event listener that manually parses and processes the token that is returned.
Steps To Reproduce
Deploy a keycloak instance
Create a User and a Client in Keycloak
Setup a C# Application using Authentication middleware:
Add a protected route and verify that the user's claims are not getting processed.
[Route("testAuth")]
[HttpGet]
[Authorize]
public async Task<IActionResult> TestAuth()
{
var token = await HttpContext.GetTokenAsync("access_token");
var claims = User.Claims;
foreach (var claim in claims)
{
Console.WriteLine($"{claim.Type}: {claim.Value}");
}
return Ok($"Authorized. {token}");
}
Navigate to the route in your browser and login to keycloak
Copy the JWT and paste it into jwt.io
Verify that the Console.WriteLine that dumped the user's claims is missing Claims that are present in the access token and does not have any "role" claims, despite the JWT existing in the token.
Is there an existing issue for this?
Describe the bug
When using
AddOpenIdConnect
, the middleware is not properly parsing the access token's JWT Token Claims from OIDC Providers.Specifically, I am testing this out with Keycloak, but I imagine this is similar with other providers too.
When using the
.AddOpenIdConnect
as an Authentication source, the integration works, however, once the access token is returned from the provider, the access token is not being properly parsed. It is able to parse some of the fields from the access token, but not others. Especiallyroles
. For example, if the token is:The resulting
User
in ASP.NET would only have thepreferred_username
name set. Some of the other fields were getting processed and put into theClaims
object, likeexp
,iat
,jti
,sub
, andsid
(maybe some others) but many are missing. In the debugger, I only had 8 total Claims on the user. The user was missing a lot of the more detailed fields likeroles
,name
,email
,family_name
, etc.This made it impossible to lock down routes using
[Authorize(Roles = "Admin")]
, as none of the user's roles were getting populated into their Claims, even if you set theoptions.TokenValidationParameters.RoleClaimType = "roles"
, it would not properly parse out the user's roles.As a workaround for this, I had to add a custom event listener to the
OnTokenValidated
event and manually parsed out the Users roles and append them to the User's Identity:I am VERY certain that this is a bug with the Microsoft Authentication library, and this workaround should not be required from my understanding. See also this StackOverflow question
Expected Behavior
Expected the Token to be properly parsed without needing to add a custom event listener that manually parses and processes the token that is returned.
Steps To Reproduce
Add a protected route and verify that the user's claims are not getting processed.
Console.WriteLine
that dumped the user's claims is missing Claims that are present in the access token and does not have any "role" claims, despite the JWT existing in the token.Exceptions (if any)
No response
.NET Version
No response
Anything else?
The text was updated successfully, but these errors were encountered: