private async Task <string> SerializeAuthorizationCodeAsync( ClaimsPrincipal principal, AuthenticationProperties properties, OpenIdConnectRequest request, OpenIdConnectResponse response) { // Note: claims in authorization codes are never filtered as they are supposed to be opaque: // SerializeAccessTokenAsync and SerializeIdentityTokenAsync are responsible of ensuring // that subsequent access and identity tokens are correctly filtered. // Create a new ticket containing the updated properties. var ticket = new AuthenticationTicket(principal, properties, Scheme.Name); ticket.Properties.IssuedUtc = Options.SystemClock.UtcNow; // Only set the expiration date if a lifetime was specified in either the ticket or the options. var lifetime = ticket.GetAuthorizationCodeLifetime() ?? Options.AuthorizationCodeLifetime; if (lifetime.HasValue) { ticket.Properties.ExpiresUtc = ticket.Properties.IssuedUtc + lifetime.Value; } // Associate a random identifier with the authorization code. ticket.SetTokenId(Guid.NewGuid().ToString()); // Store the code_challenge, code_challenge_method and nonce parameters for later comparison. ticket.SetProperty(OpenIdConnectConstants.Properties.CodeChallenge, request.CodeChallenge) .SetProperty(OpenIdConnectConstants.Properties.CodeChallengeMethod, request.CodeChallengeMethod) .SetProperty(OpenIdConnectConstants.Properties.Nonce, request.Nonce); // Store the original redirect_uri sent by the client application for later comparison. ticket.SetProperty(OpenIdConnectConstants.Properties.OriginalRedirectUri, request.GetProperty <string>(OpenIdConnectConstants.Properties.OriginalRedirectUri)); // Remove the unwanted properties from the authentication ticket. ticket.RemoveProperty(OpenIdConnectConstants.Properties.AuthorizationCodeLifetime) .RemoveProperty(OpenIdConnectConstants.Properties.TokenUsage); var notification = new SerializeAuthorizationCodeContext(Context, Scheme, Options, request, response, ticket) { DataFormat = Options.AuthorizationCodeFormat }; await Provider.SerializeAuthorizationCode(notification); if (notification.IsHandled || !string.IsNullOrEmpty(notification.AuthorizationCode)) { return(notification.AuthorizationCode); } if (notification.DataFormat == null) { throw new InvalidOperationException("A data formatter must be provided."); } var result = notification.DataFormat.Protect(ticket); Logger.LogTrace("A new authorization code was successfully generated using " + "the specified data format: {Code} ; {Claims} ; {Properties}.", result, ticket.Principal.Claims, ticket.Properties.Items); return(result); }
/// <summary> /// Represents an event called when serializing an authorization code. /// </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 SerializeAuthorizationCode(SerializeAuthorizationCodeContext context) => OnSerializeAuthorizationCode(context);