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> 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(); } }
public async Task <IActionResult> SpMetadataAsync(string partyId) { logger.ScopeTrace(() => "Up, SP Metadata request."); logger.SetScopeProperty(Constants.Logs.UpPartyId, partyId); var party = RouteBinding.UpParty != null ? await tenantRepository.GetAsync <SamlUpParty>(partyId) : null; var signMetadata = party != null ? party.SignMetadata : false; var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : signMetadata, includeSignatureValidationCertificates : false); var acsDestination = new Uri(UrlCombine.Combine(HttpContext.GetHostWithTenantAndTrack(), RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlAcs)); var singleLogoutDestination = new Uri(UrlCombine.Combine(HttpContext.GetHostWithTenantAndTrack(), RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlSingleLogout)); var entityDescriptor = new EntityDescriptor(samlConfig, signMetadata); if (party != null) { entityDescriptor.ValidUntil = new TimeSpan(0, 0, settings.SamlMetadataLifetime).Days; } var trackCertificates = GetTrackCertificates(); entityDescriptor.SPSsoDescriptor = new SPSsoDescriptor { //AuthnRequestsSigned = true, //WantAssertionsSigned = true, SigningCertificates = trackCertificates, AssertionConsumerServices = new AssertionConsumerService[] { new AssertionConsumerService { Binding = ToSamleBindingUri(party?.AuthnBinding?.ResponseBinding), Location = acsDestination }, }, }; entityDescriptor.SPSsoDescriptor.SingleLogoutServices = new SingleLogoutService[] { new SingleLogoutService { Binding = ToSamleBindingUri(party?.LogoutBinding?.ResponseBinding), Location = singleLogoutDestination }, }; if (party?.MetadataIncludeEncryptionCertificates == true) { entityDescriptor.SPSsoDescriptor.EncryptionCertificates = trackCertificates; entityDescriptor.SPSsoDescriptor.SetDefaultEncryptionMethods(); } if (party?.MetadataNameIdFormats?.Count > 0) { entityDescriptor.SPSsoDescriptor.NameIDFormats = party.MetadataNameIdFormats.Select(nf => new Uri(nf)); } if (party?.MetadataAttributeConsumingServices?.Count() > 0) { var attributeConsumingServices = new List <AttributeConsumingService>(); foreach (var aItem in party.MetadataAttributeConsumingServices) { var attributeConsumingService = new AttributeConsumingService { ServiceName = new ServiceName(aItem.ServiceName.Name, aItem.ServiceName.Lang) }; attributeConsumingService.RequestedAttributes = aItem.RequestedAttributes.Select(ra => string.IsNullOrEmpty(ra.NameFormat) ? new RequestedAttribute(ra.Name, ra.IsRequired) : new RequestedAttribute(ra.Name, ra.IsRequired, ra.NameFormat)); attributeConsumingServices.Add(attributeConsumingService); } entityDescriptor.SPSsoDescriptor.AttributeConsumingServices = attributeConsumingServices; } if (party?.MetadataContactPersons?.Count() > 0) { entityDescriptor.ContactPersons = GetContactPersons(party.MetadataContactPersons); } return(new Saml2Metadata(entityDescriptor).CreateMetadata().ToActionResult()); }