예제 #1
0
        internal IdentityProvider(IdentityProviderElement config, ISPOptions spOptions)
        {
            singleSignOnServiceUrl = config.DestinationUrl;
            EntityId = new EntityId(config.EntityId);
            binding  = config.Binding;
            AllowUnsolicitedAuthnResponse = config.AllowUnsolicitedAuthnResponse;
            metadataUrl    = config.MetadataUrl;
            LoadMetadata   = config.LoadMetadata;
            this.spOptions = spOptions;

            var certificate = config.SigningCertificate.LoadCertificate();

            if (certificate != null)
            {
                signingKey = certificate.PublicKey.Key;
            }

            try
            {
                if (LoadMetadata)
                {
                    DoLoadMetadata();
                }

                Validate();
            }
            catch (WebException)
            {
                // If we had a web exception, the metadata failed. It will
                // be automatically retried.
            }
        }
예제 #2
0
        /// <summary>
        /// Gets the certificate specifications.
        /// </summary>
        /// <param name="endpoint">The endpoint.</param>
        /// <returns>A list of certificate validation specifications for this endpoint</returns>
        public static List <ICertificateSpecification> GetCertificateSpecifications(IdentityProviderElement endpoint)
        {
            var specs = new List <ICertificateSpecification>();

            if (endpoint.CertificateValidations != null && endpoint.CertificateValidations.Count > 0)
            {
                foreach (var elem in endpoint.CertificateValidations)
                {
                    try
                    {
                        var val = (ICertificateSpecification)Activator.CreateInstance(Type.GetType(elem.Type));
                        specs.Add(val);
                    }
                    catch (Exception e)
                    {
                        Logging.LoggerProvider.LoggerFor(typeof(SpecificationFactory)).Error(e.Message, e);
                    }
                }
            }

            if (specs.Count == 0)
            {
                // Add default specification
                specs.Add(new DefaultCertificateSpecification());
            }

            return(specs);
        }
예제 #3
0
 public IdentityProvider(IdentityProviderElement config)
 {
     DestinationUri = config.DestinationUri;
     Issuer         = config.Issuer;
     Binding        = config.Binding;
     certificate    = config.SigningCertificate.LoadCertificate();
 }
예제 #4
0
        internal IdentityProvider(IdentityProviderElement config, ISPOptions spOptions)
        {
            singleSignOnServiceUrl = config.DestinationUrl;
            EntityId = new EntityId(config.EntityId);
            binding  = config.Binding;
            AllowUnsolicitedAuthnResponse = config.AllowUnsolicitedAuthnResponse;
            metadataUrl = config.MetadataUrl;

            var certificate = config.SigningCertificate.LoadCertificate();

            if (certificate != null)
            {
                signingKeys.AddConfiguredItem(certificate.PublicKey.Key);
            }

            // If configured to load metadata, this will immediately do the load.
            LoadMetadata   = config.LoadMetadata;
            this.spOptions = spOptions;

            // Validate if values are only from config. If metadata is loaded, validation
            // is done on metadata load.
            if (!LoadMetadata)
            {
                Validate();
            }
        }
        internal IdentityProvider(IdentityProviderElement config, SPOptions spOptions)
        {
            singleSignOnServiceUrl = config.SignOnUrl;
            SingleLogoutServiceUrl = config.LogoutUrl;
            EntityId = new EntityId(config.EntityId);
            binding  = config.Binding;
            AllowUnsolicitedAuthnResponse = config.AllowUnsolicitedAuthnResponse;
            metadataLocation = string.IsNullOrEmpty(config.MetadataLocation)
                ? null : config.MetadataLocation;
            WantAuthnRequestsSigned = config.WantAuthnRequestsSigned;

            var certificate = config.SigningCertificate.LoadCertificate();

            if (certificate != null)
            {
                signingKeys.AddConfiguredKey(
                    new X509RawDataKeyIdentifierClause(certificate));
            }

            foreach (var ars in config.ArtifactResolutionServices)
            {
                ArtifactResolutionServiceUrls[ars.Index] = ars.Location;
            }

            // If configured to load metadata, this will immediately do the load.
            this.spOptions = spOptions;
            LoadMetadata   = config.LoadMetadata;

            // Validate if values are only from config. If metadata is loaded, validation
            // is done on metadata load.
            if (!LoadMetadata)
            {
                Validate();
            }
        }
예제 #6
0
        private static void TestMissingConfig(IdentityProviderElement config, string missingElement)
        {
            Action a = () => new IdentityProvider(config, Options.FromConfiguration.SPOptions);

            string expectedMessage = "Missing " + missingElement + " configuration on Idp " + config.EntityId + ".";

            a.ShouldThrow <ConfigurationErrorsException>(expectedMessage);
        }
예제 #7
0
        /// <summary>
        /// Performs the attribute query against the specified IdP endpoint and adds the resulting attributes to <c>Saml20Identity.Current</c>.
        /// </summary>
        /// <param name="context">The http context.</param>
        /// <param name="endPoint">The IdP to perform the query against.</param>
        public void PerformQuery(HttpContext context, IdentityProviderElement endPoint)
        {
            var nameIdFormat = StateService.Get <string>(Saml20AbstractEndpointHandler.IdpNameIdFormat);

            if (string.IsNullOrEmpty(nameIdFormat))
            {
                nameIdFormat = Saml20Constants.NameIdentifierFormats.Persistent;
            }

            PerformQuery(context, endPoint, nameIdFormat);
        }
예제 #8
0
        /// <summary>
        /// Performs the attribute query against the specified IdP endpoint and adds the resulting attributes to <c>Saml20Identity.Current</c>.
        /// </summary>
        /// <param name="context">The http context.</param>
        /// <param name="endPoint">The IdP to perform the query against.</param>
        /// <param name="nameIdFormat">The name id format.</param>
        public void PerformQuery(HttpContext context, IdentityProviderElement endPoint, string nameIdFormat)
        {
            Logger.DebugFormat("{0}.{1} called", GetType(), "PerformQuery()");

            var builder = new HttpSoapBindingBuilder(context);

            var name = new NameId
            {
                Value  = Saml20Identity.Current.Name,
                Format = nameIdFormat
            };

            _attrQuery.Subject.Items = new object[] { name };
            _attrQuery.SamlAttribute = _attributes.ToArray();

            var query = new XmlDocument();

            query.LoadXml(Serialization.SerializeToXmlString(_attrQuery));

            XmlSignatureUtils.SignDocument(query, Id);
            if (query.FirstChild is XmlDeclaration)
            {
                query.RemoveChild(query.FirstChild);
            }

            Logger.DebugFormat(TraceMessages.AttrQuerySent, endPoint.Metadata.GetAttributeQueryEndpointLocation(), query.OuterXml);

            Stream s;

            try
            {
                s = builder.GetResponse(endPoint.Metadata.GetAttributeQueryEndpointLocation(), query.OuterXml, endPoint.AttributeQuery);
            }
            catch (Exception e)
            {
                Logger.Error(e.Message, e);
                throw;
            }

            var parser = new HttpSoapBindingParser(s);
            var status = parser.GetStatus();

            if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success)
            {
                Logger.ErrorFormat(ErrorMessages.AttrQueryStatusNotSuccessful, Serialization.SerializeToXmlString(status));
                throw new Saml20Exception(status.StatusMessage);
            }

            bool isEncrypted;
            var  xmlAssertion = Saml20SignonHandler.GetAssertion(parser.SamlMessage, out isEncrypted);

            if (isEncrypted)
            {
                var ass = new Saml20EncryptedAssertion((RSA)Saml2Config.GetConfig().ServiceProvider.SigningCertificat
예제 #9
0
        private static void AddIdP(SustainsysSaml2Section section, IdentityProviderElement newProvider)
        {
            var isReadonly = typeof(ConfigurationElementCollection).GetField("bReadOnly",
                                                                             System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            isReadonly.SetValue(section.IdentityProviders, false);
            var providers = typeof(ConfigurationElementCollection).GetMethod("BaseAdd",
                                                                             System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
                                                                             null, new[] { typeof(ConfigurationElement) }, null);

            providers.Invoke(section.IdentityProviders, new[] { newProvider });
        }
예제 #10
0
        private IdentityProviderElement CreateConfig()
        {
            var config = new IdentityProviderElement();

            config.AllowConfigEdit(true);
            config.Binding            = Saml2BindingType.HttpPost;
            config.SigningCertificate = new CertificateElement();
            config.SigningCertificate.AllowConfigEdit(true);
            config.SigningCertificate.FileName = "Kentor.AuthServices.Tests.pfx";
            config.SignOnUrl = new Uri("http://idp.example.com/acs");
            config.EntityId  = "http://idp.example.com";

            return(config);
        }
예제 #11
0
        /// <summary>
        /// Handles a request.
        /// </summary>
        /// <param name="context">The context.</param>
        protected override void Handle(HttpContext context)
        {
            Logger.Debug(TraceMessages.LogoutHandlerCalled);

            // Some IDP's are known to fail to set an actual value in the SOAPAction header
            // so we just check for the existence of the header field.
            if (Array.Exists(context.Request.Headers.AllKeys, s => s == SoapConstants.SoapAction))
            {
                HandleSoap(context, context.Request.InputStream);
                return;
            }

            if (!string.IsNullOrEmpty(context.Request.Params["SAMLart"]))
            {
                HandleArtifact(context);
                return;
            }

            if (!string.IsNullOrEmpty(context.Request.Params["SAMLResponse"]))
            {
                HandleResponse(context);
            }
            else if (!string.IsNullOrEmpty(context.Request.Params["SAMLRequest"]))
            {
                HandleRequest(context);
            }
            else
            {
                IdentityProviderElement idpEndpoint = null;

                var idpId = StateService.Get <string>(IdpSessionIdKey);
                if (!string.IsNullOrEmpty(idpId))
                {
                    idpEndpoint = RetrieveIDPConfiguration(StateService.Get <string>(IdpLoginSessionKey));
                }

                if (idpEndpoint == null)
                {
                    // TODO: Reconsider how to accomplish this.
                    context.User = null;
                    FormsAuthentication.SignOut();

                    Logger.ErrorFormat(ErrorMessages.UnknownIdentityProvider, string.Empty);
                    throw new Saml20Exception(string.Format(ErrorMessages.UnknownIdentityProvider, string.Empty));
                }

                TransferClient(idpEndpoint, context);
            }
        }
예제 #12
0
        internal IdentityProvider(IdentityProviderElement config)
        {
            AssertionConsumerServiceUrl = config.DestinationUri;
            EntityId = new EntityId(config.EntityId);
            Binding  = config.Binding;
            AllowUnsolicitedAuthnResponse = config.AllowUnsolicitedAuthnResponse;

            var certificate = config.SigningCertificate.LoadCertificate();

            if (certificate != null)
            {
                SigningKey = certificate.PublicKey.Key;
            }

            if (config.LoadMetadata)
            {
                LoadMetadata();
            }

            Validate();
        }
예제 #13
0
        /// <summary>
        /// This method converts the received SAML assertion into an <see cref="IPrincipal"/>.
        /// </summary>
        /// <param name="assertion">The assertion.</param>
        /// <param name="point">The point.</param>
        /// <returns>The <see cref="IPrincipal"/>.</returns>
        internal static IPrincipal InitSaml20Identity(Saml20Assertion assertion, IdentityProviderElement point)
        {
            var isPersistentPseudonym = assertion.Subject.Format == Saml20Constants.NameIdentifierFormats.Persistent;

            // Protocol-level support for persistent pseudonyms: If a mapper has been configured, use it here before constructing the principal.
            var subjectIdentifier = assertion.Subject.Value;

            if (isPersistentPseudonym && point.PersistentPseudonym != null)
            {
                var persistentPseudonymMapper = point.PersistentPseudonym.GetMapper();

                if (persistentPseudonymMapper != null)
                {
                    subjectIdentifier = persistentPseudonymMapper.MapIdentity(assertion.Subject);
                }
            }

            // Create identity
            var identity = new Saml20Identity(subjectIdentifier, assertion.Attributes, isPersistentPseudonym ? assertion.Subject.Value : null);

            return(new GenericPrincipal(identity, new string[] { }));
        }
예제 #14
0
 private IdentityProvider ToIdentityProvider(IdentityProviderElement idp)
 {
     return(new IdentityProvider
     {
         AllowIdPInitiatedSso = idp.AllowIdPInitiatedSso,
         AllowReplayAttacks = idp.AllowReplayAttacks,
         ArtifactResolution = ToArtifactResolution(idp.ArtifactResolution),
         AttributeQuery = ToAttributeQuery(idp.AttributeQuery),
         CertificateValidationTypes = idp.CertificateValidations.Select(v => v.Type).ToList(),
         CommonDomainCookie = idp.CommonDomainCookie.AllKeys.ToDictionary(k => k, k => idp.CommonDomainCookie[k].Value),
         Default = idp.Default,
         Endpoints = new IdentityProviderEndpoints(idp.Endpoints.Select(e => ToIdentityProviderEndpoint(e))),
         ForceAuth = idp.ForceAuth,
         Id = idp.Id,
         IsPassive = idp.IsPassive,
         Metadata = idp.Metadata,
         Name = idp.Name,
         OmitAssertionSignatureCheck = idp.OmitAssertionSignatureCheck,
         PersistentPseudonym = ToPersistentPseudonym(idp.PersistentPseudonym),
         QuirksMode = idp.QuirksMode,
         ResponseEncoding = idp.ResponseEncoding
     });
 }
예제 #15
0
        /// <summary>
        /// Transfers the client.
        /// </summary>
        /// <param name="idp">The identity provider.</param>
        /// <param name="context">The context.</param>
        private void TransferClient(IdentityProviderElement idp, HttpContext context)
        {
            var request = Saml20LogoutRequest.GetDefault();

            // Determine which endpoint to use from the configuration file or the endpoint metadata.
            var destination = DetermineEndpointConfiguration(BindingType.Redirect, idp.Endpoints.LogoutEndpoint, idp.Metadata.IDPSLOEndpoints);

            request.Destination = destination.Url;

            var nameIdFormat = StateService.Get <string>(IdpNameIdFormat);

            request.SubjectToLogOut.Format = nameIdFormat;

            // Handle POST binding
            if (destination.Binding == BindingType.Post)
            {
                var builder = new HttpPostBindingBuilder(destination);
                request.Destination           = destination.Url;
                request.Reason                = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = StateService.Get <string>(IdpNameId);
                request.SessionIndex          = StateService.Get <string>(IdpSessionIdKey);

                var requestDocument = request.GetXml();
                XmlSignatureUtils.SignDocument(requestDocument, request.Id);
                builder.Request = requestDocument.OuterXml;

                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "POST", builder.Request);

                builder.GetPage().ProcessRequest(context);
                context.Response.End();
                return;
            }

            // Handle Redirect binding
            if (destination.Binding == BindingType.Redirect)
            {
                request.Destination           = destination.Url;
                request.Reason                = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = StateService.Get <string>(IdpNameId);
                request.SessionIndex          = StateService.Get <string>(IdpSessionIdKey);

                var builder = new HttpRedirectBindingBuilder
                {
                    Request    = request.GetXml().OuterXml,
                    SigningKey = Saml2Config.GetConfig().ServiceProvider.SigningCertificate.GetCertificate().PrivateKey
                };

                var redirectUrl = destination.Url + "?" + builder.ToQuery();
                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "REDIRECT", redirectUrl);

                context.Response.Redirect(redirectUrl, true);
                return;
            }

            // Handle Artifact binding
            if (destination.Binding == BindingType.Artifact)
            {
                request.Destination           = destination.Url;
                request.Reason                = Saml20Constants.Reasons.User;
                request.SubjectToLogOut.Value = StateService.Get <string>(IdpNameId);
                request.SessionIndex          = StateService.Get <string>(IdpSessionIdKey);

                Logger.DebugFormat(TraceMessages.LogoutRequestSent, idp.Id, "ARTIFACT", request.GetXml().OuterXml);

                var builder = new HttpArtifactBindingBuilder(context);
                builder.RedirectFromLogout(destination, request, Guid.NewGuid().ToString("N"));
            }

            Logger.Error(ErrorMessages.EndpointBindingInvalid);
            throw new Saml20Exception(ErrorMessages.EndpointBindingInvalid);
        }
예제 #16
0
        private static void WriteIdPSettings(string samlLoginUrl, string samlThumbprint, string idp, IdentityProviderElement newProvider, CertificateElement newCert)
        {
            var providerReadonly = typeof(IdentityProviderElement).GetField("isReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            providerReadonly.SetValue(newProvider, false);
            var providerIndexer = typeof(IdentityProviderElement).GetProperties(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
                                  .First(p => p.GetIndexParameters().Select(i => i.ParameterType).SequenceEqual(new[] { typeof(string) }));

            providerIndexer.SetValue(newProvider, idp, new[] { "entityId" });
            providerIndexer.SetValue(newProvider, new System.Uri(samlLoginUrl), new[] { "signOnUrl" });
            providerIndexer.SetValue(newProvider, true, new[] { "allowUnsolicitedAuthnResponse" });
            providerIndexer.SetValue(newProvider, Saml2BindingType.HttpRedirect, new[] { "binding" });
            var certReadonly = typeof(CertificateElement).GetField("isReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            certReadonly.SetValue(newCert, false);
            var certIndexer = typeof(IdentityProviderElement).GetProperties(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
                              .First(p => p.GetIndexParameters().Select(i => i.ParameterType).SequenceEqual(new[] { typeof(string) }));

            certIndexer.SetValue(newCert, StoreName.My, new[] { "storeName" });
            certIndexer.SetValue(newCert, StoreLocation.CurrentUser, new[] { "storeLocation" });
            certIndexer.SetValue(newCert, X509FindType.FindByThumbprint, new[] { "x509FindType" });
            certIndexer.SetValue(newCert, samlThumbprint, new[] { "findValue" });
            providerIndexer.SetValue(newProvider, newCert, new[] { "signingCertificate" });
        }
예제 #17
0
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="keys">The keys.</param>
        /// <param name="identityProvider">The identity provider.</param>
        /// <returns>List of trusted certificate signers.</returns>
        public static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(ICollection <KeyDescriptor> keys, IdentityProviderElement identityProvider)
        {
            if (keys == null)
            {
                throw new ArgumentNullException("keys");
            }

            var result = new List <AsymmetricAlgorithm>(keys.Count);

            foreach (var keyDescriptor in keys)
            {
                foreach (KeyInfoClause clause in (KeyInfo)keyDescriptor.KeyInfo)
                {
                    // Check certificate specifications
                    if (clause is KeyInfoX509Data)
                    {
                        var cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause);
                        if (!CertificateSatisfiesSpecifications(identityProvider, cert))
                        {
                            continue;
                        }
                    }

                    var key = XmlSignatureUtils.ExtractKey(clause);
                    result.Add(key);
                }
            }

            return(result);
        }
예제 #18
0
        public static string SetIdpConfiguration(Context context, int tenantId, bool startup = false)
        {
            var contractSettings = TenantUtilities.GetContractSettings(context, tenantId);

            if (contractSettings == null ||
                contractSettings.SamlCompanyCode.IsNullOrEmpty() ||
                contractSettings.SamlLoginUrl.IsNullOrEmpty() ||
                contractSettings.SamlThumbprint.IsNullOrEmpty())
            {
                return(null);
            }
            if (!FindCert(context, contractSettings.SamlThumbprint))
            {
                return(null);
            }
            try
            {
                var section  = (SustainsysSaml2Section)ConfigurationManager.GetSection("sustainsys.saml2");
                var loginUrl = contractSettings.SamlLoginUrl;
                var idp      = loginUrl.TrimEnd(new[] { '/' }).Substring(0, loginUrl.LastIndexOf('/') + 1);
                if (processing)
                {
                    System.Threading.Thread.Sleep(300);
                }
                if (processing == false)
                {
                    processing = true;
                    try
                    {
                        IdentityProviderElement newProvider = null;
                        CertificateElement      newCert     = null;
                        var provider = section.IdentityProviders.FirstOrDefault(p => p.EntityId == idp);
                        if (provider != null)
                        {
                            string signOnUrl = provider.SignOnUrl.ToString();
                            string findValue = provider.SigningCertificate.FindValue;
                            if (signOnUrl == contractSettings.SamlLoginUrl &&
                                findValue == contractSettings.SamlThumbprint)
                            {
                                return($"~/Saml2/SignIn?idp={idp}");
                            }
                            else
                            {
                                newProvider = provider;
                                newCert     = provider.SigningCertificate;
                                WriteIdPSettings(contractSettings?.SamlLoginUrl, contractSettings?.SamlThumbprint, idp, newProvider, newCert);
                                try
                                {
                                    var spOptions = new SPOptions(SustainsysSaml2Section.Current);
                                    var options   = new Options(spOptions);
                                    SustainsysSaml2Section.Current.IdentityProviders.RegisterIdentityProviders(options);
                                    SustainsysSaml2Section.Current.Federations.RegisterFederations(options);
                                    var optionsFromConfiguration = typeof(Options).GetField("optionsFromConfiguration",
                                                                                            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
                                    optionsFromConfiguration.SetValue(null, new Lazy <Options>(() => options, true));
                                    Sustainsys.Saml2.Mvc.Saml2Controller.Options = Options.FromConfiguration;
                                }
                                catch
                                {
                                    WriteIdPSettings(signOnUrl, findValue, idp, newProvider, newCert);
                                    throw;
                                }
                            }
                        }
                        else
                        {
                            newProvider = new IdentityProviderElement();
                            newCert     = new CertificateElement();
                            WriteIdPSettings(contractSettings?.SamlLoginUrl, contractSettings?.SamlThumbprint, idp, newProvider, newCert);
                            AddIdP(section, newProvider);
                            if (startup == false)
                            {
                                var spOptions = new SPOptions(SustainsysSaml2Section.Current);
                                var options   = new Options(spOptions);
                                SustainsysSaml2Section.Current.IdentityProviders.RegisterIdentityProviders(options);
                                SustainsysSaml2Section.Current.Federations.RegisterFederations(options);
                                var optionsFromConfiguration = typeof(Options).GetField("optionsFromConfiguration",
                                                                                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
                                optionsFromConfiguration.SetValue(null, new Lazy <Options>(() => options, true));
                                Sustainsys.Saml2.Mvc.Saml2Controller.Options = Options.FromConfiguration;
                            }
                        }
                    }
                    finally
                    {
                        processing = false;
                    }
                }
                return($"~/Saml2/SignIn?idp={idp}");
            }
            catch (System.Exception e)
            {
                new SysLogModel(context, e);
                return(null);
            }
        }
예제 #19
0
        /// <summary>
        /// Transfers the client.
        /// </summary>
        /// <param name="identityProvider">The identity provider.</param>
        /// <param name="request">The request.</param>
        /// <param name="context">The context.</param>
        private void TransferClient(IdentityProviderElement identityProvider, Saml20AuthnRequest request, HttpContext context)
        {
            // Set the last IDP we attempted to login at.
            StateService.Set(IdpTempSessionKey, identityProvider.Id);

            // Determine which endpoint to use from the configuration file or the endpoint metadata.
            var destination = DetermineEndpointConfiguration(BindingType.Redirect, identityProvider.Endpoints.SignOnEndpoint, identityProvider.Metadata.SSOEndpoints);

            request.Destination = destination.Url;

            if (identityProvider.ForceAuth)
            {
                request.ForceAuthn = true;
            }

            // Check isPassive status
            var isPassiveFlag = StateService.Get <bool?>(IdpIsPassive);

            if (isPassiveFlag != null && (bool)isPassiveFlag)
            {
                request.IsPassive = true;
                StateService.Set(IdpIsPassive, null);
            }

            if (identityProvider.IsPassive)
            {
                request.IsPassive = true;
            }

            // Check if request should forceAuthn
            var forceAuthnFlag = StateService.Get <bool?>(IdpForceAuthn);

            if (forceAuthnFlag != null && (bool)forceAuthnFlag)
            {
                request.ForceAuthn = true;
                StateService.Set(IdpForceAuthn, null);
            }

            // Check if protocol binding should be forced
            if (identityProvider.Endpoints.SignOnEndpoint != null)
            {
                if (!string.IsNullOrEmpty(identityProvider.Endpoints.SignOnEndpoint.ForceProtocolBinding))
                {
                    request.ProtocolBinding = identityProvider.Endpoints.SignOnEndpoint.ForceProtocolBinding;
                }
            }

            // Save request message id to session
            StateService.Set(ExpectedInResponseToSessionKey, request.Id);

            switch (destination.Binding)
            {
            case BindingType.Redirect:
                Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpRedirect);

                var redirectBuilder = new HttpRedirectBindingBuilder
                {
                    SigningKey = _certificate.PrivateKey,
                    Request    = request.GetXml().OuterXml
                };

                Logger.DebugFormat(TraceMessages.AuthnRequestSent, redirectBuilder.Request);


                var redirectLocation = request.Destination + (request.Destination.Contains("?") ? "&" : "?") + redirectBuilder.ToQuery();
                context.Response.Redirect(redirectLocation, true);
                break;

            case BindingType.Post:
                Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpPost);

                var postBuilder = new HttpPostBindingBuilder(destination);

                // Honor the ForceProtocolBinding and only set this if it's not already set
                if (string.IsNullOrEmpty(request.ProtocolBinding))
                {
                    request.ProtocolBinding = Saml20Constants.ProtocolBindings.HttpPost;
                }

                var requestXml = request.GetXml();
                XmlSignatureUtils.SignDocument(requestXml, request.Id);
                postBuilder.Request = requestXml.OuterXml;

                Logger.DebugFormat(TraceMessages.AuthnRequestSent, postBuilder.Request);

                postBuilder.GetPage().ProcessRequest(context);
                break;

            case BindingType.Artifact:
                Logger.DebugFormat(TraceMessages.AuthnRequestPrepared, identityProvider.Id, Saml20Constants.ProtocolBindings.HttpArtifact);

                var artifactBuilder = new HttpArtifactBindingBuilder(context);

                // Honor the ForceProtocolBinding and only set this if it's not already set
                if (string.IsNullOrEmpty(request.ProtocolBinding))
                {
                    request.ProtocolBinding = Saml20Constants.ProtocolBindings.HttpArtifact;
                }

                Logger.DebugFormat(TraceMessages.AuthnRequestSent, request.GetXml().OuterXml);

                artifactBuilder.RedirectFromLogin(destination, request);
                break;

            default:
                Logger.Error(ErrorMessages.EndpointBindingInvalid);
                throw new Saml20Exception(ErrorMessages.EndpointBindingInvalid);
            }
        }
예제 #20
0
 /// <summary>
 /// Determines whether the certificate is satisfied by all specifications.
 /// </summary>
 /// <param name="idp">The identity provider.</param>
 /// <param name="cert">The cert.</param>
 /// <returns><c>true</c> if certificate is satisfied by all specifications; otherwise, <c>false</c>.</returns>
 private static bool CertificateSatisfiesSpecifications(IdentityProviderElement idp, X509Certificate2 cert)
 {
     return(SpecificationFactory.GetCertificateSpecifications(idp).All(spec => spec.IsSatisfiedBy(cert)));
 }
 private IdentityProvider ToIdentityProvider(IdentityProviderElement idp)
 {
     return new IdentityProvider
     {
         AllowIdPInitiatedSso = idp.AllowIdPInitiatedSso,
         AllowReplayAttacks = idp.AllowReplayAttacks,
         ArtifactResolution = ToArtifactResolution(idp.ArtifactResolution),
         AttributeQuery = ToAttributeQuery(idp.AttributeQuery),
         CertificateValidationTypes = idp.CertificateValidations.Select(v => v.Type).ToList(),
         CommonDomainCookie = idp.CommonDomainCookie.AllKeys.ToDictionary(k => k, k => idp.CommonDomainCookie[k].Value),
         Default = idp.Default,
         Endpoints = new IdentityProviderEndpoints(idp.Endpoints.Select(e => ToIdentityProviderEndpoint(e))),
         ForceAuth = idp.ForceAuth,
         Id = idp.Id,
         IsPassive = idp.IsPassive,
         Metadata = idp.Metadata,
         Name = idp.Name,
         OmitAssertionSignatureCheck = idp.OmitAssertionSignatureCheck,
         PersistentPseudonym = ToPersistentPseudonym(idp.PersistentPseudonym),
         QuirksMode = idp.QuirksMode,
         ResponseEncoding = idp.ResponseEncoding
     };
 }
예제 #22
0
        /// <summary>
        /// Is called before the assertion is made into a strongly typed representation
        /// </summary>
        /// <param name="context">The HttpContext.</param>
        /// <param name="elem">The assertion element.</param>
        /// <param name="endpoint">The endpoint.</param>
        protected virtual void PreHandleAssertion(HttpContext context, XmlElement elem, IdentityProviderElement endpoint)
        {
            Logger.DebugFormat(TraceMessages.AssertionPrehandlerCalled);

            if (endpoint != null && endpoint.Endpoints.LogoutEndpoint != null && !string.IsNullOrEmpty(endpoint.Endpoints.LogoutEndpoint.TokenAccessor))
            {
                var idpTokenAccessor = Activator.CreateInstance(Type.GetType(endpoint.Endpoints.LogoutEndpoint.TokenAccessor, false)) as ISaml20IdpTokenAccessor;
                if (idpTokenAccessor != null)
                {
                    Logger.DebugFormat("{0}.{1} called", idpTokenAccessor.GetType(), "ReadToken");
                    idpTokenAccessor.ReadToken(elem);
                    Logger.DebugFormat("{0}.{1} finished", idpTokenAccessor.GetType(), "ReadToken");
                }
            }
        }