private async Task <AuthenticationTicket> DeserializeIdentityTokenAsync(string token, OpenIdConnectRequest request) { var notification = new DeserializeIdentityTokenContext(Context, Scheme, Options, request, token) { SecurityTokenHandler = Options.IdentityTokenHandler }; // Note: ValidateAudience and ValidateLifetime are always set to false: // if necessary, the audience and the expiration can be validated // in InvokeIntrospectionEndpointAsync or InvokeTokenEndpointAsync. notification.TokenValidationParameters = new TokenValidationParameters { IssuerSigningKeys = Options.SigningCredentials.Select(credentials => credentials.Key) .Where(key => key is AsymmetricSecurityKey), NameClaimType = OpenIdConnectConstants.Claims.Name, RoleClaimType = OpenIdConnectConstants.Claims.Role, ValidIssuer = Context.GetIssuer(Options), ValidateAudience = false, ValidateLifetime = false }; await Provider.DeserializeIdentityToken(notification); if (notification.IsHandled || notification.Ticket != null) { notification.Ticket?.SetTokenUsage(OpenIdConnectConstants.TokenUsages.IdToken); return(notification.Ticket); } if (notification.SecurityTokenHandler == null) { throw new InvalidOperationException("A security token handler must be provided."); } SecurityToken securityToken; ClaimsPrincipal principal; try { if (!notification.SecurityTokenHandler.CanReadToken(token)) { Logger.LogTrace("The identity token '{Token}' was rejected by the security token handler.", token); return(null); } principal = notification.SecurityTokenHandler.ValidateToken(token, notification.TokenValidationParameters, out securityToken); } catch (Exception exception) { Logger.LogDebug("An exception occured while deserializing an identity token: {Exception}.", exception); return(null); } // Parameters stored in AuthenticationProperties are lost // when the identity token is serialized using a security token handler. // To mitigate that, they are inferred from the claims or the security token. var properties = new AuthenticationProperties { ExpiresUtc = securityToken.ValidTo, IssuedUtc = securityToken.ValidFrom }; var ticket = new AuthenticationTicket(principal, properties, Scheme.Name) .SetAudiences(principal.FindAll(OpenIdConnectConstants.Claims.Audience).Select(claim => claim.Value)) .SetConfidentialityLevel(principal.GetClaim(OpenIdConnectConstants.Claims.ConfidentialityLevel)) .SetPresenters(principal.FindAll(OpenIdConnectConstants.Claims.AuthorizedParty).Select(claim => claim.Value)) .SetTokenId(principal.GetClaim(OpenIdConnectConstants.Claims.JwtId)) .SetTokenUsage(principal.GetClaim(OpenIdConnectConstants.Claims.TokenUsage)); // Ensure that the received ticket is an identity token. if (!ticket.IsIdentityToken()) { Logger.LogTrace("The received token was not an identity token: {Token}.", token); return(null); } Logger.LogTrace("The identity token '{Token}' was successfully validated using " + "the specified security token handler: {Claims} ; {Properties}.", token, ticket.Principal.Claims, ticket.Properties.Items); return(ticket); }
/// <summary> /// Represents an event called when deserializing an identity token. /// </summary> /// <param name="context">The context instance associated with this event.</param> /// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns> public virtual Task DeserializeIdentityToken(DeserializeIdentityTokenContext context) => OnDeserializeIdentityToken(context);