/* * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) * See https://github.com/openiddict/openiddict-core for more information concerning * the license and the contributors participating to this project. */ using System; using System.Diagnostics; using System.Security.Claims; using System.Threading.Tasks; using AspNet.Security.OpenIdConnect.Extensions; using AspNet.Security.OpenIdConnect.Server; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Protocols.OpenIdConnect; namespace OpenIddict.Infrastructure { public partial class OpenIddictProvider : OpenIdConnectServerProvider where TUser : class where TApplication : class where TAuthorization : class where TScope : class where TToken : class { public override async Task SerializeRefreshToken([NotNull] SerializeRefreshTokenContext context) { var services = context.HttpContext.RequestServices.GetRequiredService>(); Debug.Assert(context.Request.RequestType == OpenIdConnectRequestType.TokenRequest, "The request should be a token request."); Debug.Assert(!context.Request.IsClientCredentialsGrantType(), "A refresh token should not be issued when using grant_type=client_credentials."); // Note: a null value could be returned by FindByIdAsync if the user was removed after the initial // check made by GrantAuthorizationCode/GrantRefreshToken/GrantResourceOwnerCredentials. // In this case, throw an exception to abort the token request. var user = await services.Users.FindByIdAsync(context.Ticket.Principal.GetClaim(ClaimTypes.NameIdentifier)); if (user == null) { throw new InvalidOperationException("The token request was aborted because the user associated " + "with the refresh token was not found in the database."); } string identifier; // If the client application sending the token request is known, // ensure the token is attached to the corresponding client entity. if (!string.IsNullOrEmpty(context.Request.ClientId)) { var application = await services.Applications.FindByIdAsync(context.Request.ClientId); if (application == null) { throw new InvalidOperationException("The application cannot be retrieved from the database."); } // Persist a new token entry in the database and attach it // to the user and the client application it is issued to. identifier = await services.Users.CreateTokenAsync(user, context.Request.ClientId, OpenIdConnectConstants.TokenTypeHints.RefreshToken); } else { // Persist a new token entry in the database // and attach it to the user it corresponds to. identifier = await services.Users.CreateTokenAsync(user, OpenIdConnectConstants.TokenTypeHints.RefreshToken); } if (string.IsNullOrEmpty(identifier)) { throw new InvalidOperationException("The unique key associated with a refresh token cannot be null or empty."); } // Attach the key returned by the underlying store // to the refresh token to override the default GUID // generated by the OpenID Connect server middleware. context.Ticket.SetTicketId(identifier); } } }