public override async Task <string> CreateRefreshTokenAsync(RefreshTokenCreationRequest request) { Logger.LogDebug("Creating refresh token"); int lifetime; if (request.Client.RefreshTokenExpiration == TokenExpiration.Absolute) { Logger.LogDebug("Setting an absolute lifetime: {absoluteLifetime}", request.Client.AbsoluteRefreshTokenLifetime); lifetime = request.Client.AbsoluteRefreshTokenLifetime; } else { lifetime = request.Client.SlidingRefreshTokenLifetime; if (request.Client.AbsoluteRefreshTokenLifetime > 0 && lifetime > request.Client.AbsoluteRefreshTokenLifetime) { Logger.LogWarning( "Client {clientId}'s configured " + nameof(request.Client.SlidingRefreshTokenLifetime) + " of {slidingLifetime} exceeds its " + nameof(request.Client.AbsoluteRefreshTokenLifetime) + " of {absoluteLifetime}. The refresh_token's sliding lifetime will be capped to the absolute lifetime", request.Client.ClientId, lifetime, request.Client.AbsoluteRefreshTokenLifetime); lifetime = request.Client.AbsoluteRefreshTokenLifetime; } Logger.LogDebug("Setting a sliding lifetime: {slidingLifetime}", lifetime); } var formCollection = await _scopedHttpContextRequestForm.GetFormCollectionAsync(); var originGrantType = formCollection["grant_type"]; var refreshToken = new RefreshTokenExtra() { Subject = request.Subject, ClientId = request.Client.ClientId, Description = request.Description, AuthorizedScopes = request.AuthorizedScopes, AuthorizedResourceIndicators = request.AuthorizedResourceIndicators, CreationTime = Clock.UtcNow.UtcDateTime, Lifetime = lifetime, OriginGrantType = originGrantType }; refreshToken.SetAccessToken(request.AccessToken, request.RequestedResourceIndicator); var handle = await RefreshTokenStore.StoreRefreshTokenAsync(refreshToken); return(handle); }
/// <summary> /// Creates the refresh token. /// </summary> /// <returns> /// The refresh token handle /// </returns> public virtual async Task <string> CreateRefreshTokenAsync(RefreshTokenCreationRequest request) { using var activity = Tracing.ServiceActivitySource.StartActivity("DefaultRefreshTokenService.CreateRefreshToken"); Logger.LogDebug("Creating refresh token"); int lifetime; if (request.Client.RefreshTokenExpiration == TokenExpiration.Absolute) { Logger.LogDebug("Setting an absolute lifetime: {absoluteLifetime}", request.Client.AbsoluteRefreshTokenLifetime); lifetime = request.Client.AbsoluteRefreshTokenLifetime; } else { lifetime = request.Client.SlidingRefreshTokenLifetime; if (request.Client.AbsoluteRefreshTokenLifetime > 0 && lifetime > request.Client.AbsoluteRefreshTokenLifetime) { Logger.LogWarning( "Client {clientId}'s configured " + nameof(request.Client.SlidingRefreshTokenLifetime) + " of {slidingLifetime} exceeds its " + nameof(request.Client.AbsoluteRefreshTokenLifetime) + " of {absoluteLifetime}. The refresh_token's sliding lifetime will be capped to the absolute lifetime", request.Client.ClientId, lifetime, request.Client.AbsoluteRefreshTokenLifetime); lifetime = request.Client.AbsoluteRefreshTokenLifetime; } Logger.LogDebug("Setting a sliding lifetime: {slidingLifetime}", lifetime); } var refreshToken = new RefreshToken { Subject = request.Subject, SessionId = request.AccessToken.SessionId, ClientId = request.Client.ClientId, Description = request.Description, AuthorizedScopes = request.AuthorizedScopes, AuthorizedResourceIndicators = request.AuthorizedResourceIndicators, CreationTime = Clock.UtcNow.UtcDateTime, Lifetime = lifetime, }; refreshToken.SetAccessToken(request.AccessToken, request.RequestedResourceIndicator); var handle = await RefreshTokenStore.StoreRefreshTokenAsync(refreshToken); return(handle); }
/// <inheritdoc/> public Task <string> CreateRefreshTokenAsync(RefreshTokenCreationRequest request) { return(Inner.CreateRefreshTokenAsync(request)); }
protected async override Task <(string accessToken, string refreshToken)> CreateAccessTokenAsync(ValidatedTokenRequest request) { var formCollection = _scopedHttpContextRequestForm.GetFormCollection(); var grantType = formCollection["grant_type"]; var tokenRequest = new TokenCreationRequest { Subject = request.Subject, ValidatedResources = request.ValidatedResources, ValidatedRequest = request }; bool createRefreshToken; var authorizedScopes = Enumerable.Empty <string>(); IEnumerable <string> authorizedResourceIndicators = null; if (request.AuthorizationCode != null) { createRefreshToken = request.ValidatedResources.Resources.OfflineAccess; // createRefreshToken = request.AuthorizationCode.RequestedScopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess); // load the client that belongs to the authorization code Client client = null; if (request.AuthorizationCode.ClientId != null) { // todo: do we need this check? client = await Clients.FindEnabledClientByIdAsync(request.AuthorizationCode.ClientId); } if (client == null) { throw new InvalidOperationException("Client does not exist anymore."); } tokenRequest.Subject = request.AuthorizationCode.Subject; tokenRequest.Description = request.AuthorizationCode.Description; authorizedScopes = request.AuthorizationCode.RequestedScopes; authorizedResourceIndicators = request.AuthorizationCode.RequestedResourceIndicators; } else if (request.DeviceCode != null) { createRefreshToken = request.DeviceCode.AuthorizedScopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess); Client client = null; if (request.DeviceCode.ClientId != null) { // todo: do we need this check? client = await Clients.FindEnabledClientByIdAsync(request.DeviceCode.ClientId); } if (client == null) { throw new InvalidOperationException("Client does not exist anymore."); } tokenRequest.Subject = request.DeviceCode.Subject; tokenRequest.Description = request.DeviceCode.Description; authorizedScopes = request.DeviceCode.AuthorizedScopes; } else { createRefreshToken = request.RequestedScopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess); authorizedScopes = request.ValidatedResources.RawScopeValues; } var at = await TokenService.CreateAccessTokenAsync(tokenRequest); object obj; if (_scopedStorage.TryGetValue(Constants.ScopedRequestType.OverrideTokenIssuedAtTime, out obj)) { DateTime issuedAtTime = obj is DateTime ? (DateTime)obj : default; at.CreationTime = issuedAtTime; } var finalScopes = at.Scopes.ToList(); if (createRefreshToken) { if (!finalScopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess)) { finalScopes.Add(IdentityServerConstants.StandardScopes.OfflineAccess); } } else { if (finalScopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess)) { finalScopes.Remove(IdentityServerConstants.StandardScopes.OfflineAccess); } } var accessToken = await TokenService.CreateSecurityTokenAsync(at); string refreshToken = null; if (createRefreshToken) { var rtRequest = new RefreshTokenCreationRequest { Client = request.Client, Subject = tokenRequest.Subject, Description = tokenRequest.Description, AuthorizedScopes = authorizedScopes, AuthorizedResourceIndicators = authorizedResourceIndicators, AccessToken = at, RequestedResourceIndicator = request.RequestedResourceIndicator, }; refreshToken = await RefreshTokenService.CreateRefreshTokenAsync(rtRequest); } if (_scopedStorage.TryGetValue(Constants.ScopedRequestType.ExtensionGrantValidationContext, out obj)) { var extensionGrantValidationContext = obj as ExtensionGrantValidationContext; if (extensionGrantValidationContext.Request.GrantType == FluffyBunny4.Constants.GrantType.TokenExchangeMutate) { var refreshTokenStoreGrantStoreHashAccessor = _refreshTokenStore as IGrantStoreHashAccessor; var referenceTokenStoreGrantStoreHashAccessor = _referenceTokenStore as IGrantStoreHashAccessor; _scopedStorage.TryGetValue(Constants.ScopedRequestType.PersistedGrantExtra, out obj); var persistedGrantExtra = _scopedStorage.Get <PersistedGrantExtra>(Constants.ScopedRequestType.PersistedGrantExtra); var subjectToken = _scopedStorage.Get <string>(Constants.ScopedRequestType.SubjectToken); var fixedSubjectToken = subjectToken.Substring(2); var newKey = referenceTokenStoreGrantStoreHashAccessor.GetHashedKey(accessToken); var originalKey = referenceTokenStoreGrantStoreHashAccessor.GetHashedKey(fixedSubjectToken); await _persistedGrantStore.CopyAsync(newKey, originalKey); await _persistedGrantStore.RemoveAsync(newKey); if (!createRefreshToken && !string.IsNullOrWhiteSpace(persistedGrantExtra.RefreshTokenKey)) { // need to kill the old refresh token, as this mutate didn't ask for a new one. await _persistedGrantStore.RemoveAsync(persistedGrantExtra.RefreshTokenKey); } else { newKey = refreshTokenStoreGrantStoreHashAccessor.GetHashedKey(refreshToken); await _persistedGrantStore.CopyAsync(newKey, persistedGrantExtra.RefreshTokenKey); await _persistedGrantStore.RemoveAsync(newKey); } // we need to point the old access_token and refresh_token to this new set; return(subjectToken, null); // mutate doesn't get to get the refresh_token back, the original holder of it is the only owner. } } switch (grantType) { case FluffyBunny4.Constants.GrantType.ArbitraryIdentity: case FluffyBunny4.Constants.GrantType.ArbitraryToken: case OidcConstants.GrantTypes.DeviceCode: case FluffyBunny4.Constants.GrantType.TokenExchange: case FluffyBunny4.Constants.GrantType.TokenExchangeMutate: if (!accessToken.Contains('.')) { accessToken = $"1_{accessToken}"; } if (!string.IsNullOrWhiteSpace(refreshToken)) { refreshToken = $"1_{refreshToken}"; } break; default: if (!accessToken.Contains('.')) { accessToken = $"0_{accessToken}"; } if (!string.IsNullOrWhiteSpace(refreshToken)) { refreshToken = $"0_{refreshToken}"; } break; } return(accessToken, refreshToken); // return (accessToken, null); }
private async Task <TokenResponse> ProcessArbitraryTokenTokenResponse(TokenRequestValidationResult validationResult) { var subject = validationResult.ValidatedRequest.Subject.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject); var form = validationResult.ValidatedRequest.Raw; var resultClaims = new List <Claim>() { subject }; resultClaims.AddRange(_scopedOptionalClaims.Claims); var issuer = validationResult.ValidatedRequest.Raw.Get("issuer"); if (string.IsNullOrEmpty(issuer)) { issuer = _contextAccessor.HttpContext.GetIdentityServerIssuerUri(); } var atClaims = resultClaims.Distinct(new ClaimComparer()).ToList(); bool createRefreshToken; var offlineAccessClaim = atClaims.FirstOrDefault(x => x.Type == JwtClaimTypes.Scope && x.Value == IdentityServerConstants.StandardScopes.OfflineAccess); createRefreshToken = offlineAccessClaim != null; var authorizedScopes = (from c in atClaims where c.Type == JwtClaimTypes.Scope select c.Value).ToList(); var accessTokenLifetimeOverride = form.Get(Constants.AccessTokenLifetime); int accessTokenLifetime = validationResult.ValidatedRequest.AccessTokenLifetime; if (!string.IsNullOrWhiteSpace(accessTokenLifetimeOverride)) { int.TryParse(accessTokenLifetimeOverride, out accessTokenLifetime); } var at = new Token(OidcConstants.TokenTypes.AccessToken) { CreationTime = Clock.UtcNow.UtcDateTime, Issuer = issuer, Lifetime = accessTokenLifetime, Claims = atClaims, ClientId = validationResult.ValidatedRequest.ClientId, // Description = request.Description, AccessTokenType = validationResult.ValidatedRequest.AccessTokenType, AllowedSigningAlgorithms = validationResult.ValidatedRequest.Client.AllowedIdentityTokenSigningAlgorithms, }; var accessToken = await TokenService.CreateSecurityTokenAsync(at); string refreshToken = null; if (createRefreshToken) { var refreshTokenCreationRequest = new RefreshTokenCreationRequest { Subject = validationResult.ValidatedRequest.Subject, AccessToken = at, Client = validationResult.ValidatedRequest.Client, AuthorizedScopes = authorizedScopes }; refreshToken = await RefreshTokenService.CreateRefreshTokenAsync(refreshTokenCreationRequest); } var tokenResonse = new TokenResponse { AccessToken = accessToken, IdentityToken = null, RefreshToken = $"1_{refreshToken}", AccessTokenLifetime = accessTokenLifetime }; return(tokenResonse); }
/// <summary> /// Creates the access/refresh token. /// </summary> /// <param name="request">The request.</param> /// <returns></returns> /// <exception cref="System.InvalidOperationException">Client does not exist anymore.</exception> protected virtual async Task <(string accessToken, string refreshToken)> CreateAccessTokenAsync(ValidatedTokenRequest request) { var tokenRequest = new TokenCreationRequest { Subject = request.Subject, ValidatedResources = request.ValidatedResources, ValidatedRequest = request }; bool createRefreshToken = request.ValidatedResources.Resources.OfflineAccess; var authorizedScopes = Enumerable.Empty <string>(); IEnumerable <string> authorizedResourceIndicators = null; if (request.AuthorizationCode != null) { // load the client that belongs to the authorization code Client client = null; if (request.AuthorizationCode.ClientId != null) { // todo: do we need this check? client = await Clients.FindEnabledClientByIdAsync(request.AuthorizationCode.ClientId); } if (client == null) { throw new InvalidOperationException("Client does not exist anymore."); } tokenRequest.Subject = request.AuthorizationCode.Subject; tokenRequest.Description = request.AuthorizationCode.Description; authorizedScopes = request.AuthorizationCode.RequestedScopes; authorizedResourceIndicators = request.AuthorizationCode.RequestedResourceIndicators; } else if (request.DeviceCode != null) { Client client = null; if (request.DeviceCode.ClientId != null) { // todo: do we need this check? client = await Clients.FindEnabledClientByIdAsync(request.DeviceCode.ClientId); } if (client == null) { throw new InvalidOperationException("Client does not exist anymore."); } tokenRequest.Subject = request.DeviceCode.Subject; tokenRequest.Description = request.DeviceCode.Description; authorizedScopes = request.DeviceCode.AuthorizedScopes; } else { authorizedScopes = request.ValidatedResources.RawScopeValues; } var at = await TokenService.CreateAccessTokenAsync(tokenRequest); var accessToken = await TokenService.CreateSecurityTokenAsync(at); if (createRefreshToken) { var rtRequest = new RefreshTokenCreationRequest { Client = request.Client, Subject = tokenRequest.Subject, Description = tokenRequest.Description, AuthorizedScopes = authorizedScopes, AuthorizedResourceIndicators = authorizedResourceIndicators, AccessToken = at, RequestedResourceIndicator = request.RequestedResourceIndicator, }; var refreshToken = await RefreshTokenService.CreateRefreshTokenAsync(rtRequest); return(accessToken, refreshToken); } return(accessToken, null); }