private async Task <IActionResult> LogoutResponseAsync <T>(Saml2Configuration samlConfig, string inResponseTo, string relayState, string loggedOutUrl, Saml2Binding <T> binding, Saml2StatusCodes status, string sessionIndex) { binding.RelayState = relayState; var saml2LogoutResponse = new Saml2LogoutResponse(samlConfig) { InResponseTo = new Saml2Id(inResponseTo), Status = status, Destination = new Uri(loggedOutUrl), SessionIndex = sessionIndex }; binding.Bind(saml2LogoutResponse); logger.ScopeTrace($"SAML Logout response '{saml2LogoutResponse.XmlDocument.OuterXml}'."); logger.ScopeTrace($"Logged out URL '{loggedOutUrl}'."); logger.ScopeTrace("Down, SAML Logout response.", triggerEvent: true); await sequenceLogic.RemoveSequenceDataAsync <SamlDownSequenceData>(); securityHeaderLogic.AddFormAction(loggedOutUrl); if (binding is Saml2Binding <Saml2RedirectBinding> ) { return(await(binding as Saml2RedirectBinding).ToActionFormResultAsync()); } if (binding is Saml2Binding <Saml2PostBinding> ) { return(await(binding as Saml2PostBinding).ToActionFormResultAsync()); } else { throw new NotSupportedException(); } }
public async Task <IActionResult> EndSessionResponseAsync(string partyId) { logger.ScopeTrace(() => "Down, End session response."); logger.SetScopeProperty(Constants.Logs.DownPartyId, partyId); var sequenceData = await sequenceLogic.GetSequenceDataAsync <OidcDownSequenceData>(false); var rpInitiatedLogoutResponse = new RpInitiatedLogoutResponse { State = sequenceData.State, }; logger.ScopeTrace(() => $"End session response '{rpInitiatedLogoutResponse.ToJsonIndented()}'.", traceType: TraceTypes.Message); var nameValueCollection = rpInitiatedLogoutResponse.ToDictionary(); logger.ScopeTrace(() => $"Redirect Uri '{sequenceData.RedirectUri}'."); logger.ScopeTrace(() => "Down, OIDC End session response.", triggerEvent: true); await sequenceLogic.RemoveSequenceDataAsync <OidcDownSequenceData>(); if (sequenceData.RestrictFormAction) { securityHeaderLogic.AddFormAction(sequenceData.RedirectUri); } else { securityHeaderLogic.AddFormActionAllowAll(); } return(await nameValueCollection.ToRedirectResultAsync(sequenceData.RedirectUri)); }
public async Task <IActionResult> AuthenticationResponseAsync(string partyId, List <Claim> claims) { logger.ScopeTrace(() => "Down, OIDC Authentication response."); logger.SetScopeProperty(Constants.Logs.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); logger.ScopeTrace(() => $"Down, OIDC received JWT claims '{claims.ToFormattedString()}'", traceType: TraceTypes.Claim); claims = await claimTransformLogic.Transform(party.ClaimTransforms?.ConvertAll(t => (ClaimTransform)t), claims); logger.ScopeTrace(() => $"Down, OIDC output JWT claims '{claims.ToFormattedString()}'", traceType: TraceTypes.Claim); var nameValueCollection = await CreateAuthenticationAndSessionResponse(party, claims, sequenceData); var responseMode = GetResponseMode(sequenceData.ResponseMode, sequenceData.ResponseType); await sequenceLogic.RemoveSequenceDataAsync <OidcDownSequenceData>(); if (party.RestrictFormAction) { securityHeaderLogic.AddFormAction(sequenceData.RedirectUri); } else { securityHeaderLogic.AddFormActionAllowAll(); } 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(); } }
private async Task <IActionResult> AuthnResponseAsync <T>(SamlDownParty party, Saml2Configuration samlConfig, string inResponseTo, string relayState, string acsUrl, Saml2Binding <T> binding, Saml2StatusCodes status, IEnumerable <Claim> claims) { binding.RelayState = relayState; var saml2AuthnResponse = new FoxIDsSaml2AuthnResponse(settings, samlConfig) { InResponseTo = new Saml2Id(inResponseTo), Status = status, Destination = new Uri(acsUrl), }; if (status == Saml2StatusCodes.Success && party != null && claims != null) { claims = await claimTransformationsLogic.Transform(party.ClaimTransforms?.ConvertAll(t => (ClaimTransform)t), claims); saml2AuthnResponse.SessionIndex = samlClaimsDownLogic.GetSessionIndex(claims); saml2AuthnResponse.NameId = samlClaimsDownLogic.GetNameId(claims); var tokenIssueTime = DateTimeOffset.UtcNow; var tokenDescriptor = saml2AuthnResponse.CreateTokenDescriptor(samlClaimsDownLogic.GetSubjectClaims(party, claims), party.Issuer, tokenIssueTime, party.IssuedTokenLifetime); var authnContext = claims.FindFirstValue(c => c.Type == ClaimTypes.AuthenticationMethod); var authenticationInstant = claims.FindFirstValue(c => c.Type == ClaimTypes.AuthenticationInstant); var authenticationStatement = saml2AuthnResponse.CreateAuthenticationStatement(authnContext, DateTime.Parse(authenticationInstant)); var subjectConfirmation = saml2AuthnResponse.CreateSubjectConfirmation(tokenIssueTime, party.SubjectConfirmationLifetime); await saml2AuthnResponse.CreateSecurityTokenAsync(tokenDescriptor, authenticationStatement, subjectConfirmation); } binding.Bind(saml2AuthnResponse); logger.ScopeTrace($"SAML Authn response '{saml2AuthnResponse.XmlDocument.OuterXml}'."); logger.ScopeTrace($"Acs URL '{acsUrl}'."); logger.ScopeTrace("Down, SAML Authn response.", triggerEvent: true); await sequenceLogic.RemoveSequenceDataAsync <SamlDownSequenceData>(); securityHeaderLogic.AddFormAction(acsUrl); if (binding is Saml2Binding <Saml2RedirectBinding> ) { return(await(binding as Saml2RedirectBinding).ToActionFormResultAsync()); } else if (binding is Saml2Binding <Saml2PostBinding> ) { return(await(binding as Saml2PostBinding).ToActionFormResultAsync()); } else { throw new NotSupportedException(); } }
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(); } }