protected override async Task <IActionResult> AuthorizationCodeGrantAsync(TClient client, TokenRequest tokenRequest, bool validatePkce, CodeVerifierSecret codeVerifierSecret) { var authCodeGrant = await oauthAuthCodeGrantDownLogic.GetAndValidateAuthCodeGrantAsync(tokenRequest.Code, tokenRequest.RedirectUri, tokenRequest.ClientId); Console.WriteLine($"authCodeGrant not null: {authCodeGrant != null}"); if (validatePkce) { await ValidatePkceAsync(client, authCodeGrant.CodeChallenge, authCodeGrant.CodeChallengeMethod, codeVerifierSecret); } logger.ScopeTrace(() => "Down, OIDC Authorization code grant accepted.", triggerEvent: true); try { var tokenResponse = new TokenResponse { TokenType = IdentityConstants.TokenTypes.Bearer, ExpiresIn = client.AccessTokenLifetime, }; string algorithm = IdentityConstants.Algorithms.Asymmetric.RS256; var claims = authCodeGrant.Claims.ToClaimList(); var scopes = authCodeGrant.Scope.ToSpaceList(); tokenResponse.AccessToken = await jwtDownLogic.CreateAccessTokenAsync(client, claims, scopes, algorithm); var responseTypes = new[] { IdentityConstants.ResponseTypes.IdToken, IdentityConstants.ResponseTypes.Token }; tokenResponse.IdToken = await jwtDownLogic.CreateIdTokenAsync(client, claims, scopes, authCodeGrant.Nonce, responseTypes, null, tokenResponse.AccessToken, algorithm); if (scopes.Contains(IdentityConstants.DefaultOidcScopes.OfflineAccess)) { tokenResponse.RefreshToken = await oauthRefreshTokenGrantDownLogic.CreateRefreshTokenGrantAsync(client, claims, authCodeGrant.Scope); } logger.ScopeTrace(() => $"Token response '{tokenResponse.ToJsonIndented()}'.", traceType: TraceTypes.Message); logger.ScopeTrace(() => "Down, OIDC Token response.", triggerEvent: true); return(new JsonResult(tokenResponse)); } catch (KeyException kex) { throw new OAuthRequestException(kex.Message, kex) { RouteBinding = RouteBinding, Error = IdentityConstants.ResponseErrors.ServerError }; } }
private async Task <Dictionary <string, string> > CreateAuthenticationAndSessionResponse(TParty party, List <Claim> claims, OidcDownSequenceData sequenceData) { try { var authenticationResponse = new AuthenticationResponse { State = sequenceData.State, ExpiresIn = party.Client.AccessTokenLifetime, }; var sessionResponse = new SessionResponse { SessionState = claims.FindFirstValue(c => c.Type == JwtClaimTypes.SessionId).GetSessionStateValue(party.Client.ClientId, sequenceData.RedirectUri) }; logger.ScopeTrace(() => $"Response type '{sequenceData.ResponseType}'."); var responseTypes = sequenceData.ResponseType.ToSpaceList(); if (responseTypes.Where(rt => rt.Contains(IdentityConstants.ResponseTypes.Code)).Any()) { authenticationResponse.Code = await oauthAuthCodeGrantDownLogic.CreateAuthCodeGrantAsync(party.Client as TClient, claims, sequenceData.RedirectUri, sequenceData.Scope, sequenceData.Nonce, sequenceData.CodeChallenge, sequenceData.CodeChallengeMethod); } string algorithm = IdentityConstants.Algorithms.Asymmetric.RS256; if (responseTypes.Where(rt => rt.Contains(IdentityConstants.ResponseTypes.Token)).Any()) { authenticationResponse.TokenType = IdentityConstants.TokenTypes.Bearer; authenticationResponse.AccessToken = await jwtDownLogic.CreateAccessTokenAsync(party.Client as TClient, claims, sequenceData.Scope?.ToSpaceList(), algorithm); } if (responseTypes.Where(rt => rt.Contains(IdentityConstants.ResponseTypes.IdToken)).Any()) { authenticationResponse.IdToken = await jwtDownLogic.CreateIdTokenAsync(party.Client as TClient, claims, sequenceData.Scope?.ToSpaceList(), sequenceData.Nonce, responseTypes, authenticationResponse.Code, authenticationResponse.AccessToken, algorithm); } logger.ScopeTrace(() => $"Authentication response '{authenticationResponse.ToJsonIndented()}'.", traceType: TraceTypes.Message); var nameValueCollection = authenticationResponse.ToDictionary(); if (!sessionResponse.SessionState.IsNullOrWhiteSpace()) { logger.ScopeTrace(() => $"Session response '{sessionResponse.ToJsonIndented()}'.", traceType: TraceTypes.Message); nameValueCollection = nameValueCollection.AddToDictionary(sessionResponse); } logger.ScopeTrace(() => $"Redirect Uri '{sequenceData.RedirectUri}'."); logger.ScopeTrace(() => "Down, OIDC Authentication response.", triggerEvent: true); return(nameValueCollection); } catch (KeyException kex) { var errorAuthenticationResponse = new AuthenticationResponse { State = sequenceData.State, Error = IdentityConstants.ResponseErrors.ServerError, ErrorDescription = kex.Message }; return(errorAuthenticationResponse.ToDictionary()); } }
public async Task <IActionResult> AuthenticationResponseAsync(string partyId, List <Claim> claims) { logger.ScopeTrace("Down, OIDC Authentication response."); logger.SetScopeProperty("downPartyId", partyId); var party = await tenantRepository.GetAsync <TParty>(partyId); if (party.Client == null) { throw new NotSupportedException("Party Client not configured."); } var sequenceData = await sequenceLogic.GetSequenceDataAsync <OidcDownSequenceData>(false); claims = await claimTransformationsLogic.Transform(party.ClaimTransforms?.ConvertAll(t => (ClaimTransform)t), claims); var authenticationResponse = new AuthenticationResponse { State = sequenceData.State, ExpiresIn = party.Client.AccessTokenLifetime, }; var sessionResponse = new SessionResponse { SessionState = claims.FindFirstValue(c => c.Type == JwtClaimTypes.SessionId).GetSessionStateValue(party.Client.ClientId, sequenceData.RedirectUri) }; logger.ScopeTrace($"Response type '{sequenceData.ResponseType}'."); var responseTypes = sequenceData.ResponseType.ToSpaceList(); if (responseTypes.Where(rt => rt.Contains(IdentityConstants.ResponseTypes.Code)).Any()) { authenticationResponse.Code = await oauthAuthCodeGrantDownLogic.CreateAuthCodeGrantAsync(party.Client as TClient, claims, sequenceData.RedirectUri, sequenceData.Scope, sequenceData.Nonce, sequenceData.CodeChallenge, sequenceData.CodeChallengeMethod); } string algorithm = IdentityConstants.Algorithms.Asymmetric.RS256; if (responseTypes.Where(rt => rt.Contains(IdentityConstants.ResponseTypes.Token)).Any()) { authenticationResponse.TokenType = IdentityConstants.TokenTypes.Bearer; authenticationResponse.AccessToken = await jwtDownLogic.CreateAccessTokenAsync(party.Client as TClient, claims, sequenceData.Scope?.ToSpaceList(), algorithm); } if (responseTypes.Where(rt => rt.Contains(IdentityConstants.ResponseTypes.IdToken)).Any()) { authenticationResponse.IdToken = await jwtDownLogic.CreateIdTokenAsync(party.Client as TClient, claims, sequenceData.Scope?.ToSpaceList(), sequenceData.Nonce, responseTypes, authenticationResponse.Code, authenticationResponse.AccessToken, algorithm); } logger.ScopeTrace($"Authentication response '{authenticationResponse.ToJsonIndented()}'."); var nameValueCollection = authenticationResponse.ToDictionary(); if (!sessionResponse.SessionState.IsNullOrWhiteSpace()) { logger.ScopeTrace($"Session response '{sessionResponse.ToJsonIndented()}'."); nameValueCollection = nameValueCollection.AddToDictionary(sessionResponse); } logger.ScopeTrace($"Redirect Uri '{sequenceData.RedirectUri}'."); logger.ScopeTrace("Down, OIDC Authentication response.", triggerEvent: true); var responseMode = GetResponseMode(sequenceData.ResponseMode, sequenceData.ResponseType); await sequenceLogic.RemoveSequenceDataAsync <OidcDownSequenceData>(); securityHeaderLogic.AddFormAction(sequenceData.RedirectUri); switch (responseMode) { case IdentityConstants.ResponseModes.FormPost: return(await nameValueCollection.ToHtmlPostContentResultAsync(sequenceData.RedirectUri)); case IdentityConstants.ResponseModes.Query: return(await nameValueCollection.ToRedirectResultAsync(sequenceData.RedirectUri)); case IdentityConstants.ResponseModes.Fragment: return(await nameValueCollection.ToFragmentResultAsync(sequenceData.RedirectUri)); default: throw new NotSupportedException(); } }