dotnet / dotnet/aspnetcore

Encrypted userinfo jwt not working

Open
#4,650 24 comments 1 reaction 0 assignees View on GitHub
affected-few area-auth enhancement severity-major
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

I'm integrating with an identity provider who uses OpenId connect with userinfo in an encrypted jwt.

Unfortunately, OpenIdConnectHandler is unable to handle this specific case. Crashes at: https://github.com/aspnet/Security/blob/beaa2b443d46ef8adaf5c2a89eb475e1893037c2/src/Microsoft.AspNetCore.Authentication.OpenIdConnect/OpenIdConnectHandler.cs#L815-L819 because userInfoEndpointJwt.Payload is null in this case

See also https://github.com/aspnet/Security/pull/517#discussion_r42279158 where @PinpointTownes suggests it will possibly crash but he can't test it versus a server with this behavior.

Since it's allowed in the openid connect spec, the handler should probably be able to handle it.

I managed to make it work by replacing the code above with this:

else if (contentType.MediaType.Equals("application/jwt", StringComparison.OrdinalIgnoreCase))
{
var validationParameters = Options.TokenValidationParameters.Clone();
validationParameters.RequireSignedTokens = false;
validationParameters.ValidateLifetime = false;
if (_configuration != null)
{
var issuer = new[] { _configuration.Issuer };
validationParameters.ValidIssuers = validationParameters.ValidIssuers?.Concat(issuer) ?? issuer;
validationParameters.IssuerSigningKeys = validationParameters.IssuerSigningKeys?.Concat(_configuration.SigningKeys)
?? _configuration.SigningKeys;
}

var princip = Options.SecurityTokenValidator.ValidateToken(userInfoResponse, validationParameters, out SecurityToken validatedToken);
var userInfoJwt = validatedToken as JwtSecurityToken;
user = JObject.FromObject(userInfoJwt.Payload);
userInfoResponse = new JwtSecurityTokenHandler().WriteToken(userInfoJwt.InnerToken);
}

But this is just an ugly workaround for this specific provider, I'm sure someone can come up with a more generic implementation which fixes both cases. (The reason I'm replacing the userInfoResponse is because later in the method the userInfoResponse is being validated and this method ALSO assumes it's unencrypted)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.