You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
3.7 KiB
71 lines
3.7 KiB
/*
|
|
* 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<TUser, TApplication, TAuthorization, TScope, TToken> : 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<OpenIddictServices<TUser, TApplication, TAuthorization, TScope, TToken>>();
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|