private async Task <string> SerializeRefreshTokenAsync( ClaimsIdentity identity, AuthenticationProperties properties, OpenIdConnectRequest request, OpenIdConnectResponse response) { // Note: claims in refresh tokens 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(identity, properties); 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.GetRefreshTokenLifetime() ?? Options.RefreshTokenLifetime; if (lifetime.HasValue) { ticket.Properties.ExpiresUtc = ticket.Properties.IssuedUtc + lifetime.Value; } // Associate a random identifier with the refresh token. ticket.SetTokenId(Guid.NewGuid().ToString()); // Remove the unwanted properties from the authentication ticket. ticket.RemoveProperty(OpenIdConnectConstants.Properties.AuthorizationCodeLifetime) .RemoveProperty(OpenIdConnectConstants.Properties.CodeChallenge) .RemoveProperty(OpenIdConnectConstants.Properties.CodeChallengeMethod) .RemoveProperty(OpenIdConnectConstants.Properties.Nonce) .RemoveProperty(OpenIdConnectConstants.Properties.OriginalRedirectUri) .RemoveProperty(OpenIdConnectConstants.Properties.TokenUsage); var notification = new SerializeRefreshTokenContext(Context, Options, request, response, ticket) { DataFormat = Options.RefreshTokenFormat }; await Options.Provider.SerializeRefreshToken(notification); if (notification.IsHandled || !string.IsNullOrEmpty(notification.RefreshToken)) { return(notification.RefreshToken); } if (notification.DataFormat == null) { throw new InvalidOperationException("A data formatter must be provided."); } var result = notification.DataFormat.Protect(ticket); Logger.LogTrace("A new refresh token was successfully generated using the " + "specified data format: {Token} ; {Claims} ; {Properties}.", result, ticket.Identity.Claims, ticket.Properties.Dictionary); return(result); }
private async Task <string> SerializeRefreshTokenAsync( ClaimsIdentity identity, AuthenticationProperties properties, OpenIdConnectRequest request, OpenIdConnectResponse response) { // properties.IssuedUtc and properties.ExpiresUtc // should always be preferred when explicitly set. if (properties.IssuedUtc == null) { properties.IssuedUtc = Options.SystemClock.UtcNow; } if (properties.ExpiresUtc == null) { properties.ExpiresUtc = properties.IssuedUtc + Options.RefreshTokenLifetime; } // Claims in refresh tokens 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. var ticket = new AuthenticationTicket(identity, properties); ticket.SetUsage(OpenIdConnectConstants.Usages.RefreshToken); // Associate a random identifier with the refresh token. ticket.SetTicketId(Guid.NewGuid().ToString()); // By default, add the client_id to the list of the // presenters allowed to use the refresh token. if (!string.IsNullOrEmpty(request.ClientId)) { ticket.SetPresenters(request.ClientId); } var notification = new SerializeRefreshTokenContext(Context, Options, request, response, ticket) { DataFormat = Options.RefreshTokenFormat }; await Options.Provider.SerializeRefreshToken(notification); if (notification.HandledResponse || !string.IsNullOrEmpty(notification.RefreshToken)) { return(notification.RefreshToken); } else if (notification.Skipped) { return(null); } return(notification.DataFormat?.Protect(ticket)); }
private async Task <string> SerializeRefreshTokenAsync( ClaimsIdentity identity, AuthenticationProperties properties, OpenIdConnectRequest request, OpenIdConnectResponse response) { // Note: claims in refresh tokens 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(identity, properties); ticket.Properties.IssuedUtc = Options.SystemClock.UtcNow; ticket.Properties.ExpiresUtc = ticket.Properties.IssuedUtc + (ticket.GetRefreshTokenLifetime() ?? Options.RefreshTokenLifetime); ticket.SetUsage(OpenIdConnectConstants.Usages.RefreshToken); // Associate a random identifier with the refresh token. ticket.SetTicketId(Guid.NewGuid().ToString()); // Remove the unwanted properties from the authentication ticket. ticket.RemoveProperty(OpenIdConnectConstants.Properties.AuthorizationCodeLifetime) .RemoveProperty(OpenIdConnectConstants.Properties.ClientId) .RemoveProperty(OpenIdConnectConstants.Properties.CodeChallenge) .RemoveProperty(OpenIdConnectConstants.Properties.CodeChallengeMethod) .RemoveProperty(OpenIdConnectConstants.Properties.Nonce) .RemoveProperty(OpenIdConnectConstants.Properties.RedirectUri); var notification = new SerializeRefreshTokenContext(Context, Options, request, response, ticket) { DataFormat = Options.RefreshTokenFormat }; await Options.Provider.SerializeRefreshToken(notification); if (notification.HandledResponse || !string.IsNullOrEmpty(notification.RefreshToken)) { return(notification.RefreshToken); } else if (notification.Skipped) { return(null); } return(notification.DataFormat?.Protect(ticket)); }
/// <summary> /// Represents an event called when serializing a refresh 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 SerializeRefreshToken(SerializeRefreshTokenContext context) => OnSerializeRefreshToken(context);