private async Task <Option <GrantedToken> > HandleApprovedRequest( string issuerName, DeviceAuthorizationData authRequest, CancellationToken cancellationToken) { var scopes = string.Join(" ", authRequest.Scopes); var grantedToken = await _tokenStore.GetValidGrantedToken(_jwksStore, scopes, authRequest.ClientId, cancellationToken) //idTokenJwsPayload: result.AuthCode.IdTokenPayload, //userInfoJwsPayload: result.AuthCode.UserInfoPayLoad) .ConfigureAwait(false); if (grantedToken == null) { var client = await _clientStore.GetById(authRequest.ClientId, cancellationToken).ConfigureAwait(false); grantedToken = await client !.GenerateToken( _jwksStore, authRequest.Scopes, issuerName, //result.AuthCode.UserInfoPayLoad, //result.AuthCode.IdTokenPayload, cancellationToken: cancellationToken //result.AuthCode.IdTokenPayload?.Claims.Where( // c => result.Client.UserClaimsToIncludeInAuthToken.Any(r => r.IsMatch(c.Type))) // .ToArray() //?? Array.Empty<Claim>()) ) .ConfigureAwait(false); await _eventPublisher.Publish( new TokenGranted( Id.Create(), grantedToken.UserInfoPayLoad?.Sub, authRequest.ClientId, string.Join(" ", authRequest.Scopes), GrantTypes.AuthorizationCode, DateTimeOffset.UtcNow)) .ConfigureAwait(false); // Fill-in the id-token if (grantedToken.IdTokenPayLoad != null) { grantedToken = grantedToken with { IdTokenPayLoad = JwtGenerator.UpdatePayloadDate(grantedToken.IdTokenPayLoad, client !.TokenLifetime), IdToken = await client.GenerateIdToken(grantedToken.IdTokenPayLoad, _jwksStore, cancellationToken) .ConfigureAwait(false) }; } await _tokenStore.AddToken(grantedToken !, cancellationToken).ConfigureAwait(false); } return(grantedToken !); } }
public async Task <EndpointResult> Generate( EndpointResult endpointResult, AuthorizationParameter authorizationParameter, ClaimsPrincipal claimsPrincipal, Client client, string?issuerName, CancellationToken cancellationToken) { var allowedTokenScopes = string.Empty; GrantedToken?grantedToken = null; var responses = authorizationParameter.ResponseType.ParseResponseTypes(); var generateIdToken = await GenerateIdTokenPayload( claimsPrincipal, authorizationParameter, issuerName, cancellationToken) .ConfigureAwait(false); if (generateIdToken is Option <JwtPayload> .Result p) { var idTokenPayload = p.Item; var payload = await GenerateUserInformationPayload( claimsPrincipal, authorizationParameter, cancellationToken) .ConfigureAwait(false); if (payload is Option <JwtPayload> .Error er) { return(EndpointResult.CreateBadRequestResult(er.Details)); } var userInformationPayload = (payload as Option <JwtPayload> .Result) !.Item; if (responses.Contains(ResponseTypeNames.Token)) { // 1. Generate an access token. var tokenScopes = authorizationParameter.Scope.ParseScopes(); allowedTokenScopes = string.Join(' ', tokenScopes); grantedToken = await _tokenStore.GetValidGrantedToken( _jwksStore, allowedTokenScopes, client.ClientId, cancellationToken, idTokenJwsPayload : userInformationPayload, userInfoJwsPayload : idTokenPayload) .ConfigureAwait(false) ?? await client.GenerateToken( _jwksStore, tokenScopes, issuerName, userInformationPayload, idTokenPayload, cancellationToken : cancellationToken, claimsPrincipal.Claims.Where( c => client.UserClaimsToIncludeInAuthToken.Any( r => r.IsMatch(c.Type))) .ToArray()) .ConfigureAwait(false); endpointResult = endpointResult with { RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter( StandardAuthorizationResponseNames.AccessTokenName, grantedToken.AccessToken) }; } AuthorizationCode?authorizationCode = null; var authorizationParameterClientId = authorizationParameter.ClientId; if (responses.Contains(ResponseTypeNames.Code)) // 2. Generate an authorization code. { var subject = claimsPrincipal.GetSubject() !; var assignedConsent = await _consentRepository .GetConfirmedConsents(subject, authorizationParameter, cancellationToken) .ConfigureAwait(false); if (assignedConsent != null) { if (authorizationParameterClientId == null || authorizationParameter.RedirectUrl == null || authorizationParameter.Scope == null) { throw new ArgumentException(Strings.MissingValues, nameof(authorizationParameter)); } // Insert a temporary authorization code // It will be used later to retrieve tha id_token or an access token. authorizationCode = new AuthorizationCode { Code = Id.Create(), RedirectUri = authorizationParameter.RedirectUrl, CreateDateTime = DateTimeOffset.UtcNow, ClientId = authorizationParameterClientId, Scopes = authorizationParameter.Scope, IdTokenPayload = idTokenPayload, UserInfoPayLoad = userInformationPayload }; endpointResult = endpointResult with { RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter( StandardAuthorizationResponseNames.AuthorizationCodeName, authorizationCode.Code) }; } } _jwtGenerator.FillInOtherClaimsIdentityTokenPayload( idTokenPayload, authorizationCode == null ? string.Empty : authorizationCode.Code, grantedToken == null ? string.Empty : grantedToken.AccessToken, client); if (grantedToken != null) // 3. Insert the stateful access token into the DB OR insert the access token into the caching. { if (authorizationParameterClientId == null || authorizationParameter.ResponseType == null) { throw new ArgumentException(Strings.MissingValues, nameof(authorizationParameter)); } await _tokenStore.AddToken(grantedToken, cancellationToken).ConfigureAwait(false); await _eventPublisher.Publish( new TokenGranted( Id.Create(), claimsPrincipal.GetSubject(), authorizationParameterClientId, allowedTokenScopes, authorizationParameter.ResponseType, DateTimeOffset.UtcNow)) .ConfigureAwait(false); } if (authorizationCode != null) // 4. Insert the authorization code into the caching. { if (client.RequirePkce) { authorizationCode = authorizationCode with { CodeChallenge = authorizationParameter.CodeChallenge ?? string.Empty, CodeChallengeMethod = authorizationParameter.CodeChallengeMethod ?? string.Empty }; } await _authorizationCodeStore.Add(authorizationCode, cancellationToken).ConfigureAwait(false); await _eventPublisher.Publish( new AuthorizationGranted( Id.Create(), claimsPrincipal.GetSubject(), authorizationParameterClientId !, DateTimeOffset.UtcNow)) .ConfigureAwait(false); } if (responses.Contains(ResponseTypeNames.IdToken)) { var idToken = await _clientStore.GenerateIdToken( authorizationParameterClientId !, idTokenPayload, _jwksStore, cancellationToken) .ConfigureAwait(false); endpointResult = endpointResult with { RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter( StandardAuthorizationResponseNames.IdTokenName, idToken) }; } if (!string.IsNullOrWhiteSpace(authorizationParameter.State)) { endpointResult = endpointResult with { RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter( StandardAuthorizationResponseNames.StateName, authorizationParameter.State) }; } var sessionState = GetSessionState( authorizationParameterClientId, authorizationParameter.OriginUrl, authorizationParameter.SessionId); if (sessionState != null) { endpointResult = endpointResult with { RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter( StandardAuthorizationResponseNames.SessionState, sessionState) }; } if (authorizationParameter.ResponseMode == ResponseModes.FormPost) { endpointResult = endpointResult with { Type = ActionResultType.RedirectToAction, RedirectInstruction = endpointResult.RedirectInstruction !.AddParameter( "redirect_uri", authorizationParameter.RedirectUrl?.AbsoluteUri) with { Action = SimpleAuthEndPoints.FormIndex } }; } // Set the response mode if (endpointResult.Type == ActionResultType.RedirectToCallBackUrl) { var responseMode = authorizationParameter.ResponseMode; if (responseMode == ResponseModes.None) { var responseTypes = authorizationParameter.ResponseType.ParseResponseTypes(); var authorizationFlow = responseTypes.GetAuthorizationFlow(authorizationParameter.State); switch (authorizationFlow) { case Option <AuthorizationFlow> .Error error: return(EndpointResult.CreateBadRequestResult(error.Details)); case Option <AuthorizationFlow> .Result r: responseMode = CoreConstants.MappingAuthorizationFlowAndResponseModes[r.Item]; break; } } endpointResult = endpointResult with { RedirectInstruction = endpointResult.RedirectInstruction !with { ResponseMode = responseMode } }; } return(endpointResult); } var e = generateIdToken as Option <JwtPayload> .Error; return(EndpointResult.CreateBadRequestResult(e !.Details)); }
public async Task <Option <GrantedToken> > Execute( AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter, AuthenticationHeaderValue?authenticationHeaderValue, X509Certificate2?certificate, string issuerName, CancellationToken cancellationToken) { var option = await ValidateParameter( authorizationCodeGrantTypeParameter, authenticationHeaderValue, certificate, issuerName, cancellationToken) .ConfigureAwait(false); if (option is Option <ValidationResult> .Error e) { return(e.Details); } var result = ((Option <ValidationResult> .Result)option).Item; // 1. Invalidate the authorization code by removing it ! await _authorizationCodeStore.Remove(result.AuthCode.Code, cancellationToken).ConfigureAwait(false); var grantedToken = await _tokenStore.GetValidGrantedToken( _jwksStore, result.AuthCode.Scopes, result.AuthCode.ClientId, cancellationToken, idTokenJwsPayload : result.AuthCode.IdTokenPayload, userInfoJwsPayload : result.AuthCode.UserInfoPayLoad) .ConfigureAwait(false); if (grantedToken == null) { grantedToken = await result.Client.GenerateToken( _jwksStore, result.AuthCode.Scopes.Split(' '), issuerName, result.AuthCode.UserInfoPayLoad, result.AuthCode.IdTokenPayload, cancellationToken, result.AuthCode.IdTokenPayload?.Claims.Where( c => result.Client.UserClaimsToIncludeInAuthToken.Any(r => r.IsMatch(c.Type))) .ToArray() ?? Array.Empty <Claim>()) .ConfigureAwait(false); await _eventPublisher.Publish( new TokenGranted( Id.Create(), grantedToken.UserInfoPayLoad?.Sub, result.AuthCode.ClientId, result.AuthCode.Scopes, GrantTypes.AuthorizationCode, DateTimeOffset.UtcNow)) .ConfigureAwait(false); // Fill-in the id-token if (grantedToken.IdTokenPayLoad != null) { grantedToken = grantedToken with { IdTokenPayLoad = JwtGenerator.UpdatePayloadDate( grantedToken.IdTokenPayLoad, result.Client.TokenLifetime), IdToken = await result !.Client.GenerateIdToken( grantedToken.IdTokenPayLoad, _jwksStore, cancellationToken) .ConfigureAwait(false) }; } await _tokenStore.AddToken(grantedToken !, cancellationToken).ConfigureAwait(false); } return(grantedToken !); }