private async Task <IActionResult> AuthnResponseDownAsync(SamlUpSequenceData sequenceData, Saml2StatusCodes status, IEnumerable <Claim> claims = null) { logger.ScopeTrace($"Response, Down type {sequenceData.DownPartyType}."); switch (sequenceData.DownPartyType) { case PartyTypes.OAuth2: throw new NotImplementedException(); case PartyTypes.Oidc: if (status == Saml2StatusCodes.Success) { var claimsLogic = serviceProvider.GetService <ClaimsLogic <OidcDownClient, OidcDownScope, OidcDownClaim> >(); return(await serviceProvider.GetService <OidcAuthDownLogic <OidcDownParty, OidcDownClient, OidcDownScope, OidcDownClaim> >().AuthenticationResponseAsync(sequenceData.DownPartyId, await claimsLogic.FromSamlToJwtClaims(claims))); } else { return(await serviceProvider.GetService <OidcAuthDownLogic <OidcDownParty, OidcDownClient, OidcDownScope, OidcDownClaim> >().AuthenticationResponseErrorAsync(sequenceData.DownPartyId, StatusToOAuth2OidcError(status))); } case PartyTypes.Saml2: return(await serviceProvider.GetService <SamlAuthnDownLogic>().AuthnResponseAsync(sequenceData.DownPartyId, status, claims)); default: throw new NotSupportedException(); } }
private async Task <IActionResult> LogoutResponseDownAsync(SamlUpSequenceData sequenceData, Saml2StatusCodes status, string sessionIndex = null) { logger.ScopeTrace($"Response, Down type {sequenceData.DownPartyType}."); switch (sequenceData.DownPartyType) { case PartyTypes.OAuth2: throw new NotImplementedException(); case PartyTypes.Oidc: if (status == Saml2StatusCodes.Success) { return(await serviceProvider.GetService <OidcEndSessionDownLogic <OidcDownParty, OidcDownClient, OidcDownScope, OidcDownClaim> >().EndSessionResponseAsync(sequenceData.DownPartyId)); } else { throw new EndpointException($"SAML up Logout failed, Status '{status}', Name '{RouteBinding.UpParty.Name}'.") { RouteBinding = RouteBinding }; } case PartyTypes.Saml2: return(await serviceProvider.GetService <SamlLogoutDownLogic>().LogoutResponseAsync(sequenceData.DownPartyId, status, sessionIndex)); default: throw new NotSupportedException(); } }
private async Task <IActionResult> AuthnResponseDownAsync(SamlUpSequenceData sequenceData, Saml2StatusCodes status, List <Claim> jwtClaims = null) { try { logger.ScopeTrace(() => $"Response, Down type {sequenceData.DownPartyLink.Type}."); switch (sequenceData.DownPartyLink.Type) { case PartyTypes.OAuth2: throw new NotImplementedException(); case PartyTypes.Oidc: if (status == Saml2StatusCodes.Success) { return(await serviceProvider.GetService <OidcAuthDownLogic <OidcDownParty, OidcDownClient, OidcDownScope, OidcDownClaim> >().AuthenticationResponseAsync(sequenceData.DownPartyLink.Id, jwtClaims)); } else { return(await serviceProvider.GetService <OidcAuthDownLogic <OidcDownParty, OidcDownClient, OidcDownScope, OidcDownClaim> >().AuthenticationResponseErrorAsync(sequenceData.DownPartyLink.Id, StatusToOAuth2OidcError(status))); } case PartyTypes.Saml2: return(await serviceProvider.GetService <SamlAuthnDownLogic>().AuthnResponseAsync(sequenceData.DownPartyLink.Id, status, jwtClaims)); default: throw new NotSupportedException(); } } catch (Exception ex) { throw new StopSequenceException("Falling authn response down", ex); } }
private async Task <IActionResult> SingleLogoutResponseAsync(SamlUpSequenceData sequenceData, Saml2StatusCodes status = Saml2StatusCodes.Success, string sessionIndex = null) { logger.SetScopeProperty(Constants.Logs.UpPartyId, sequenceData.UpPartyId); var party = await tenantRepository.GetAsync <SamlUpParty>(sequenceData.UpPartyId); ValidatePartyLogoutSupport(party); var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : true); return(await SingleLogoutResponseAsync(party, samlConfig, sequenceData.Id, sequenceData.RelayState, status, sessionIndex)); }
private async Task <IActionResult> LogoutResponseDownAsync(SamlUpSequenceData sequenceData, Saml2StatusCodes status = Saml2StatusCodes.Success) { try { logger.ScopeTrace(() => $"Response, Down type {sequenceData.DownPartyLink.Type}."); switch (sequenceData.DownPartyLink.Type) { case PartyTypes.OAuth2: throw new NotImplementedException(); case PartyTypes.Oidc: if (status == Saml2StatusCodes.Success) { return(await serviceProvider.GetService <OidcRpInitiatedLogoutDownLogic <OidcDownParty, OidcDownClient, OidcDownScope, OidcDownClaim> >().EndSessionResponseAsync(sequenceData.DownPartyLink.Id)); } else { throw new StopSequenceException($"SAML up Logout failed, Status '{status}', Name '{RouteBinding.UpParty.Name}'."); } case PartyTypes.Saml2: return(await serviceProvider.GetService <SamlLogoutDownLogic>().LogoutResponseAsync(sequenceData.DownPartyLink.Id, status, sequenceData.SessionId)); default: throw new NotSupportedException(); } } catch (StopSequenceException) { throw; } catch (Exception ex) { throw new StopSequenceException("Falling logout response down", ex); } }
private async Task <IActionResult> AuthnRequestAsync <T>(SamlUpParty party, Saml2Binding <T> binding, SamlUpSequenceData samlUpSequenceData) { var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : true); binding.RelayState = await sequenceLogic.CreateExternalSequenceIdAsync(); var saml2AuthnRequest = new Saml2AuthnRequest(samlConfig); switch (samlUpSequenceData.LoginAction) { case LoginAction.ReadSession: saml2AuthnRequest.IsPassive = true; break; case LoginAction.RequireLogin: saml2AuthnRequest.ForceAuthn = true; break; default: break; } if (party.AuthnContextClassReferences?.Count() > 0) { saml2AuthnRequest.RequestedAuthnContext = new RequestedAuthnContext { Comparison = party.AuthnContextComparison.HasValue ? (AuthnContextComparisonTypes)Enum.Parse(typeof(AuthnContextComparisonTypes), party.AuthnContextComparison.Value.ToString()) : null, AuthnContextClassRef = party.AuthnContextClassReferences, }; } binding.Bind(saml2AuthnRequest); logger.ScopeTrace(() => $"SAML Authn request '{saml2AuthnRequest.XmlDocument.OuterXml}'.", traceType: TraceTypes.Message); logger.ScopeTrace(() => $"Authn URL '{samlConfig.SingleSignOnDestination?.OriginalString}'."); logger.ScopeTrace(() => "Up, Sending SAML Authn request.", triggerEvent: true); securityHeaderLogic.AddFormActionAllowAll(); 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(); } }
private async Task <IActionResult> SingleLogoutRequestAsync(SamlUpParty party, SamlUpSequenceData sequenceData) { var session = await sessionUpPartyLogic.DeleteSessionAsync(party); await oauthRefreshTokenGrantLogic.DeleteRefreshTokenGrantsAsync(session.SessionId); if (party.DisableSingleLogout) { var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : true); return(await SingleLogoutResponseAsync(party, samlConfig, sequenceData.Id, sequenceData.RelayState)); } else { (var doSingleLogout, var singleLogoutSequenceData) = await singleLogoutDownLogic.InitializeSingleLogoutAsync(new UpPartyLink { Name = party.Name, Type = party.Type }, null, session.DownPartyLinks, session.Claims); if (doSingleLogout) { return(await singleLogoutDownLogic.StartSingleLogoutAsync(singleLogoutSequenceData)); } else { var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : true); return(await SingleLogoutResponseAsync(party, samlConfig, sequenceData.Id, sequenceData.RelayState)); } } }
private async Task <IActionResult> LogoutRequestAsync <T>(SamlUpParty party, Saml2Binding <T> binding, SamlUpSequenceData samlUpSequenceData) { var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : true); binding.RelayState = await sequenceLogic.CreateExternalSequenceIdAsync(); var saml2LogoutRequest = new Saml2LogoutRequest(samlConfig); var session = await sessionUpPartyLogic.GetSessionAsync(party); if (session == null) { return(await LogoutResponseDownAsync(samlUpSequenceData)); } try { if (!samlUpSequenceData.SessionId.Equals(session.SessionId, StringComparison.Ordinal)) { throw new Exception("Requested session ID do not match up-party session ID."); } } catch (Exception ex) { logger.Warning(ex); } saml2LogoutRequest.SessionIndex = session.ExternalSessionId; samlUpSequenceData.SessionDownPartyLinks = session.DownPartyLinks; samlUpSequenceData.SessionClaims = session.Claims; await sequenceLogic.SaveSequenceDataAsync(samlUpSequenceData); var jwtClaims = samlUpSequenceData.SessionClaims.ToClaimList(); var nameID = jwtClaims?.Where(c => c.Type == JwtClaimTypes.Subject).Select(c => c.Value).FirstOrDefault(); var nameIdFormat = jwtClaims?.Where(c => c.Type == Constants.JwtClaimTypes.SubFormat).Select(c => c.Value).FirstOrDefault(); if (!nameID.IsNullOrEmpty()) { var prePartyName = $"{party.Name}|"; if (nameID.StartsWith(prePartyName, StringComparison.Ordinal)) { nameID = nameID.Remove(0, prePartyName.Length); } if (nameIdFormat.IsNullOrEmpty()) { saml2LogoutRequest.NameId = new Saml2NameIdentifier(nameID); } else { saml2LogoutRequest.NameId = new Saml2NameIdentifier(nameID, new Uri(nameIdFormat)); } } binding.Bind(saml2LogoutRequest); logger.ScopeTrace(() => $"SAML Logout request '{saml2LogoutRequest.XmlDocument.OuterXml}'.", traceType: TraceTypes.Message); logger.ScopeTrace(() => $"Logout URL '{samlConfig.SingleLogoutDestination?.OriginalString}'."); logger.ScopeTrace(() => "Up, SAML Logout request.", triggerEvent: true); _ = await sessionUpPartyLogic.DeleteSessionAsync(party, session); await oauthRefreshTokenGrantLogic.DeleteRefreshTokenGrantsAsync(samlUpSequenceData.SessionId); securityHeaderLogic.AddFormActionAllowAll(); 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(); } }
private async Task <IActionResult> AuthnRequestAsync <T>(SamlUpParty party, Saml2Binding <T> binding, SamlUpSequenceData samlUpSequenceData) { var samlConfig = saml2ConfigurationLogic.GetSamlUpConfig(party); binding.RelayState = SequenceString; var saml2AuthnRequest = new Saml2AuthnRequest(samlConfig); switch (samlUpSequenceData.LoginAction) { case LoginAction.ReadSession: saml2AuthnRequest.IsPassive = true; break; case LoginAction.RequireLogin: saml2AuthnRequest.ForceAuthn = true; break; default: break; } binding.Bind(saml2AuthnRequest); logger.ScopeTrace($"SAML Authn request '{saml2AuthnRequest.XmlDocument.OuterXml}'."); logger.ScopeTrace($"Authn URL '{samlConfig.SingleSignOnDestination?.OriginalString}'."); logger.ScopeTrace("Up, Sending SAML Authn request.", triggerEvent: true); securityHeaderLogic.AddFormActionAllowAll(); 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(); } }