コード例 #1
0
        public static LinkIDAuthnResponse parse(ResponseType response)
        {
            String userId = null;
            Dictionary <String, List <LinkIDAttribute> > attributes = new Dictionary <string, List <LinkIDAttribute> >();

            foreach (object item in response.Items)
            {
                AssertionType assertion = (AssertionType)item;
                SubjectType   subject   = assertion.Subject;
                NameIDType    nameId    = (NameIDType)subject.Items[0];
                userId = nameId.Value;

                foreach (StatementAbstractType statement in assertion.Items)
                {
                    if (statement is AttributeStatementType)
                    {
                        AttributeStatementType attributeStatement = (AttributeStatementType)statement;
                        attributes = getAttributes(attributeStatement);
                    }
                }
            }

            LinkIDPaymentResponse      paymentResponse      = findPaymentResponse(response);
            LinkIDExternalCodeResponse externalCodeResponse = findExternalCodeResponse(response);

            return(new LinkIDAuthnResponse(userId, attributes, paymentResponse, externalCodeResponse));
        }
コード例 #2
0
        public static string GetSAMLResponse(string request, string username)
        {
            string destination = "https://login.microsoftonline.com/login.srf";
            string recipient   = "https://login.microsoftonline.com/login.srf";
            string issuer      = "https://accounts.google.com/o/saml2?idpid=C00s8nnu4";

            //XDocument xdRequest = XDocument.Parse(request);
            XNamespace xnSAML2p = "urn:oasis:names:tc:SAML:2.0:protocol";
            XNamespace xnSAML2  = "urn:oasis:names:tc:SAML:2.0:assertion";
            XNamespace xnDS     = "http://www.w3.org/2000/09/xmldsig#";

            XDocument xdResponse = new XDocument();
            var       xeResponse = new XElement(xnSAML2p + "Response");

            xeResponse.SetAttributeValue("Destination", destination);

            var responseId = Guid.NewGuid();

            xeResponse.SetAttributeValue("ID", String.Format("_{0:N}", responseId));

            //xeResponse.SetAttributeValue("InResponseTo", requestId);


            xdResponse.Add(xeResponse);



            //2019 - 12 - 11T15: 44:21.256Z
            var str = xdResponse.ToString();
            var sb  = new StringBuilder();


            ResponseType response = new ResponseType();

            // Response Main Area
            response.ID           = "_" + Guid.NewGuid().ToString();
            response.Destination  = recipient;
            response.Version      = "2.0";
            response.IssueInstant = System.DateTime.UtcNow;

            NameIDType issuerForResponse = new NameIDType();

            issuerForResponse.Value = issuer.Trim();

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType();

            status.StatusCode       = new StatusCodeType();
            status.StatusCode.Value =
                "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;



            return("");
        }
コード例 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Saml2Options" /> class.
        /// </summary>
        public Saml2Options()
        {
            EnablePIILogging        = false;
            WantAuthnRequestsSigned = false;
            ForwardChallenge        = AuthenticationScheme;
            SignInScheme            = CookieAuthenticationDefaults.AuthenticationScheme;
            SignOutScheme           = AuthenticationScheme;
            AuthenticationScheme    = Saml2Defaults.AuthenticationScheme;
            SignOutPath             = new PathString("/signedout");
            CallbackPath            = new PathString("/saml2-signin");
            DefaultRedirectUrl      = new PathString("/");
            RequireHttpsMetadata    = true;
            ForceAuthn                    = true;
            NameIDType                    = new NameIDType();
            IsPassive                     = false;
            VerifySignatureOnly           = true;
            DefaultMetadataFolderLocation = "wwwroot";
            DefaultMetadataFileName       = "Metadata";
            CreateMetadataFile            = false;
            ServiceProvider               = new ServiceProviderInfo()
            {
                HashAlgorithm             = HashAlgorithmName.SHA256,
                AssertionConsumerServices = new IndexedEndpointType[]
                {
                    new IndexedEndpointType()
                    {
                        Binding            = ProtocolBindings.HTTP_Post, //must only allow POST
                        index              = 0,
                        isDefault          = true,
                        isDefaultSpecified = true
                    }
                },
                SingleLogoutServices = new EndpointType[]
                {
                    new EndpointType()
                    {
                        Binding = ProtocolBindings.HTTP_Post //must only allow Post back to sp
                    }
                }
            };

            WantAssertionsSigned    = false;
            RequireMessageSigned    = false;
            RequestIdCookieLifetime = TimeSpan.FromMinutes(10);
            RequestCookieId         = new CookieBuilder()
            {
                IsEssential  = CookieConsentNeeded,
                HttpOnly     = true,
                SameSite     = SameSiteMode.None,
                SecurePolicy = CookieSecurePolicy.SameAsRequest,
                Expiration   = RequestIdCookieLifetime
            };
            Events = new Saml2Events();
            AllowUnsolicitedLogins = false;
        }
コード例 #4
0
        /// <summary>
        /// Identifies the subject.
        /// </summary>
        /// <param name="format">A URI reference representing the classification of string-based identifier information. If no value is specified then the value "nameid-format-unspecified" is in effect.</param>
        /// <param name="value">Value of the name</param>
        /// <param name="spProviderId">Name Identifier established by a service provider or affiliation providers for the entity.</param>
        /// <param name="nameQualifier">The security or administrative domain that qualifies the name.</param>
        /// <param name="spNameQualifier">Further qualifies a name with the name of the service provider or affiliaton provider.</param>
        /// <returns></returns>
        public SubjectBuilder SetNameId(string format, string value, string spProviderId = null, string nameQualifier = null, string spNameQualifier = null)
        {
            var nameIdType = new NameIDType
            {
                Format          = format,
                Value           = value,
                SPProvidedID    = spProviderId,
                NameQualifier   = nameQualifier,
                SPNameQualifier = spNameQualifier
            };

            ReplaceIdentifier(nameIdType);
            return(this);
        }
コード例 #5
0
        public string getUsername(String userId)
        {
            NameIdentifierMappingQueryRequest request = new NameIdentifierMappingQueryRequest();
            NameIDType nameId = new NameIDType();

            nameId.Value = userId;
            request.NameIDMappingRequest      = new NameIDMappingRequestType();
            request.NameIDMappingRequest.Item = nameId;
            this.client.NameIdentifierMappingQuery(request);

            /*
             * NameIDMappingRequestType request = new NameIDMappingRequestType();
             * this.client.NameIdentifierMappingQuery(request);
             */
            return(null);
        }
コード例 #6
0
        private static void ValidateNameID(NameIDType nameId)
        {
            if (nameId == null)
            {
                throw new ArgumentNullException("nameId");
            }

            if (string.IsNullOrEmpty(nameId.Format))
            {
                return;
            }

            if (nameId.Format == Saml2Constants.NameIdentifierFormats.Unspecified)
            {
                if (string.IsNullOrEmpty(nameId.Value))
                {
                    throw new Exception("NameID with unspecified format attribute must have a value");
                }
            }

            SamlHelper.Username = nameId.Value;
        }
コード例 #7
0
        private AttributeQueryType getAttributeQuery(string userId, string[] attributeNames)
        {
            AttributeQueryType attributeQuery = new AttributeQueryType();
            SubjectType        subject        = new SubjectType();
            NameIDType         subjectName    = new NameIDType();

            subjectName.Value      = userId;
            subject.Items          = new Object[] { subjectName };
            attributeQuery.Subject = subject;

            if (null != attributeNames)
            {
                List <AttributeType> attributes = new List <AttributeType>();
                foreach (string attributeName in attributeNames)
                {
                    AttributeType attribute = new AttributeType();
                    attribute.Name = attributeName;
                    attributes.Add(attribute);
                }
                attributeQuery.Attribute = attributes.ToArray();
            }
            return(attributeQuery);
        }
コード例 #8
0
        private static AssertionType CreateSamlAssertion(AuthnRequestType samlAuthRequest, string username)
        {
            var assertion = new AssertionType
            {
                Version      = "2.0",
                IssueInstant = DateTime.UtcNow,
                ID           = "_" + Guid.NewGuid(),
                Issuer       = new NameIDType()
                {
                    Value = $"{_context.Request.Scheme}://{_context.Request.Host}{_context.Request.PathBase}"
                }
            };

            //Assertion Subject
            var subject = new SubjectType();
            var subjectNameIdentifier = new NameIDType()
            {
                Value = username, Format = Saml2Constants.NameIdentifierFormats.Unspecified
            };
            var subjectConfirmation = new SubjectConfirmationType()
            {
                Method = Saml2Constants.SubjectConfirmationMethods.HolderOfKey,
                SubjectConfirmationData = new SubjectConfirmationDataType()
                {
                    NotOnOrAfter = DateTime.UtcNow.AddMinutes(ASSERTION_TIMEOUT_IN_MINUTES),
                    Recipient    = samlAuthRequest.AssertionConsumerServiceURL,
                    InResponseTo = samlAuthRequest.ID
                }
            };

            subject.Items     = new object[] { subjectNameIdentifier, subjectConfirmation };
            assertion.Subject = subject;

            //Assertion Conditions
            var conditions = new ConditionsType
            {
                NotBefore             = DateTime.UtcNow,
                NotBeforeSpecified    = true,
                NotOnOrAfter          = DateTime.UtcNow.AddMinutes(ASSERTION_TIMEOUT_IN_MINUTES),
                NotOnOrAfterSpecified = true,
                //TODO: samlAuthRequest.Issuer.Value should be replaced with
                Items = new ConditionAbstractType[] { new AudienceRestrictionType()
                                                      {
                                                          Audience = new string[] { samlAuthRequest.Issuer.Value }
                                                      } }
            };

            assertion.Conditions = conditions;

            //Assertion AuthnStatement
            var authStatement = new AuthnStatementType()
            {
                AuthnInstant = DateTime.UtcNow, SessionIndex = assertion.ID
            };
            var context = new AuthnContextType();

            context.ItemsElementName   = new[] { ItemsChoiceType5.AuthnContextClassRef };
            context.Items              = new object[] { "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified" };
            authStatement.AuthnContext = context;

            //Assertion AttributeStatement
            var attributeStatement = new AttributeStatementType();

            attributeStatement.Items = new AttributeType[]
            {
                //Add as many attributes as you want here, these are the user details that service provider wants, we can customise the attributes required
                // on the basis of service provider that requires this assertion
                new AttributeType {
                    Name = "username", AttributeValue = username, NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
                }
            };
            assertion.Items = new StatementAbstractType[] { authStatement, attributeStatement };

            return(assertion);
        }
コード例 #9
0
        /// <summary>
        /// GetPostSamlResponse - Returns a Base64 Encoded String with the SamlResponse in it.
        /// </summary>
        /// <param name="recipient">Recipient</param>
        /// <param name="issuer">Issuer</param>
        /// <param name="domain">Domain</param>
        /// <param name="subject">Subject</param>
        /// <param name="storeLocation">Certificate Store Location</param>
        /// <param name="storeName">Certificate Store Name</param>
        /// <param name="findType">Certificate Find Type</param>
        /// <param name="certLocation">Certificate Location</param>
        /// <param name="findValue">Certificate Find Value</param>
        /// <param name="certFile">Certificate File (used instead of the above Certificate Parameters)</param>
        /// <param name="certPassword">Certificate Password (used instead of the above Certificate Parameters)</param>
        /// <param name="attributes">A list of attributes to pass</param>
        /// <param name="signatureType">Whether to sign Response or Assertion</param>
        /// <returns>A base64Encoded string with a SAML response.</returns>
        public static string GetPostSamlResponse(string recipient, string issuer, string subject, string audience, string requestid, string nameIdPolicyFormat,
                                                 StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                                 Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType, Models.IdPOptionsModel options)
        {
            ResponseType response = new ResponseType();

            // Response Main Area
            response.ID           = "_" + Guid.NewGuid().ToString("N");
            response.Destination  = recipient;
            response.Version      = "2.0";
            response.IssueInstant = System.DateTime.UtcNow;
            response.InResponseTo = requestid;

            NameIDType issuerForResponse = new NameIDType();

            issuerForResponse.Value = issuer.Trim();

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType();

            status.StatusCode       = new StatusCodeType();
            status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            if (options.UseNamespaces)
            {
                ns.Add("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol");
                ns.Add("saml2", "urn:oasis:names:tc:SAML:2.0:assertion");
                ns.Add("ds", "http://www.w3.org/2000/09/xmldsig#");
            }
            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings();

            settings.Encoding           = Encoding.UTF8;
            settings.OmitXmlDeclaration = true;
            settings.Indent             = true;

            XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings);

            string samlString = string.Empty;

            AssertionType assertionType = SamlHelper.CreateSamlAssertion(
                issuer.Trim(), recipient.Trim(), subject.Trim(), audience.Trim(), nameIdPolicyFormat, attributes);

            response.Items = new AssertionType[] { assertionType };

            responseSerializer.Serialize(responseWriter, response, ns);
            responseWriter.Close();

            samlString = stringWriter.ToString();

            samlString = samlString.Replace("SubjectConfirmationData",
                                            string.Format("SubjectConfirmationData NotOnOrAfter=\"{0:o}\" Recipient=\"{1}\" InResponseTo=\"{2:D}\" ",
                                                          DateTime.UtcNow.AddMinutes(5), recipient, requestid));

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            //doc.LoadXml(samlString);
            byte[] samlBytes = Encoding.UTF8.GetBytes(samlString);
            var    ms        = new MemoryStream(samlBytes);

            doc.Load(ms);

            X509Certificate2 cert = null;

            if (System.IO.File.Exists(certFile))
            {
                try
                {
                    cert = new X509Certificate2(certFile, certPassword);
                }
                catch (Exception ex)
                {
                    ;
                }
            }
            else
            {
                X509Store store = new X509Store(storeName, storeLocation);
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection coll = store.Certificates.Find(findType, findValue, false);
                if (coll.Count < 1)
                {
                    throw new ArgumentException("Unable to locate certificate");
                }
                cert = coll[0];
                store.Close();
            }

            XmlElement signature =
                SigningHelper.SignDoc(doc, cert, "ID",
                                      signatureType == SigningHelper.SignatureType.Response ? response.ID : assertionType.ID,
                                      options);

            doc.DocumentElement.InsertBefore(signature,
                                             doc.DocumentElement.ChildNodes[1]);

            if (SamlHelper.Logger.IsDebugEnabled)
            {
                SamlHelper.Logger.DebugFormat(
                    "Saml Assertion before encoding = {0}",
                    doc.OuterXml.ToString());
            }
            //string responseStr = doc.OuterXml;

            //byte[] base64EncodedBytes =
            //    Encoding.UTF8.GetBytes(responseStr);

            if (options.IncludeXmlDeclaration)
            {
                //Create an XML declaration.
                XmlDeclaration xmldecl;
                xmldecl = doc.CreateXmlDeclaration("1.0", "UTF-8", "no");
                //Add the new node to the document.
                XmlElement root = doc.DocumentElement;
                doc.InsertBefore(xmldecl, root);
            }

            byte[] base64EncodedBytes = Encoding.UTF8.GetBytes(doc.OuterXml);

            string returnValue = System.Convert.ToBase64String(
                base64EncodedBytes);

            return(returnValue);
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: quan-shi-au/MySaml
        public static XmlElement GetSignature(string recipient, string issuer, string domain, string subject,
                                              StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                              Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType)
        {
            ResponseType response = new ResponseType();

            // Response Main Area
            response.ID           = "_" + Guid.NewGuid().ToString();
            response.Destination  = recipient;
            response.Version      = "2.0";
            response.IssueInstant = System.DateTime.UtcNow;

            NameIDType issuerForResponse = new NameIDType();

            issuerForResponse.Value = issuer.Trim();

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType();

            status.StatusCode       = new StatusCodeType();
            status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;

            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings();

            settings.OmitXmlDeclaration = true;
            settings.Indent             = true;
            settings.Encoding           = Encoding.UTF8;

            XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings);

            string samlString = string.Empty;

            AssertionType assertionType = CreateSamlAssertion(
                issuer.Trim(), recipient.Trim(), domain.Trim(), subject.Trim(), attributes);

            response.Items = new AssertionType[] { assertionType };

            responseSerializer.Serialize(responseWriter, response);
            responseWriter.Close();

            samlString = stringWriter.ToString();

            samlString = samlString.Replace("SubjectConfirmationData",
                                            string.Format("SubjectConfirmationData NotOnOrAfter=\"{0:o}\" Recipient=\"{1}\"",
                                                          DateTime.UtcNow.AddMinutes(5), recipient));

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);
            X509Certificate2 cert = null;

            cert = new X509Certificate2(certFile, certPassword);

            XmlElement signature =
                SigningHelper.SignDoc(doc, cert, "ID",
                                      signatureType == SigningHelper.SignatureType.Response ? response.ID : assertionType.ID);

            return(signature);
        }
コード例 #11
0
        /// <summary>
        /// GetPostSamlResponse - Returns a Base64 Encoded String with the SamlResponse in it.
        /// </summary>
        /// <param name="recipient">Recipient</param>
        /// <param name="issuer">Issuer</param>
        /// <param name="domain">Domain</param>
        /// <param name="subject">Subject</param>
        /// <param name="storeLocation">Certificate Store Location</param>
        /// <param name="storeName">Certificate Store Name</param>
        /// <param name="findType">Certificate Find Type</param>
        /// <param name="certLocation">Certificate Location</param>
        /// <param name="findValue">Certificate Find Value</param>
        /// <param name="certFile">Certificate File (used instead of the above Certificate Parameters)</param>
        /// <param name="certPassword">Certificate Password (used instead of the above Certificate Parameters)</param>
        /// <param name="attributes">A list of attributes to pass</param>
        /// <param name="signatureType">Whether to sign Response or Assertion</param>
        /// <returns>A base64Encoded string with a SAML response.</returns>
        public static string BuildPostSamlResponse(string recipient, string issuer, string domain, string subject,
                                                   StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                                   Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType)
        {
            ResponseType response = new ResponseType
            {
                // Response Main Area
                ID           = "_" + Guid.NewGuid().ToString(),
                Destination  = recipient,
                Version      = "2.0",
                IssueInstant = DateTime.UtcNow
            };

            NameIDType issuerForResponse = new NameIDType
            {
                Value = issuer.Trim()
            };

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType
            {
                StatusCode = new StatusCodeType()
            };

            status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol");
            ns.Add("saml2", "urn:oasis:names:tc:SAML:2.0:assertion");

            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings
            {
                OmitXmlDeclaration = true,
                Indent             = true,
                Encoding           = Encoding.UTF8
            };

            XmlWriter responseWriter = XmlWriter.Create(stringWriter, settings);

            string samlString = string.Empty;

            AssertionType assertionType = Saml2Helper.CreateSamlAssertion(
                issuer.Trim(), recipient.Trim(), domain.Trim(), subject.Trim(), attributes);

            response.Items = new AssertionType[] { assertionType };

            responseSerializer.Serialize(responseWriter, response, ns);
            responseWriter.Close();

            samlString = stringWriter.ToString();

            samlString = samlString.Replace("SubjectConfirmationData",
                                            string.Format("SubjectConfirmationData NotOnOrAfter=\"{0:o}\" Recipient=\"{1}\"",
                                                          DateTime.UtcNow.AddMinutes(5), recipient));

            samlString = samlString.Replace("<saml2:Assertion ", "<saml2:Assertion xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\" ");

            samlString = samlString.Replace("<saml2:AuthnContextClassRef>AuthnContextClassRef</saml2:AuthnContextClassRef>", "<saml2:AuthnContextClassRef>" + issuer + "</saml2:AuthnContextClassRef>");

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);
            X509Certificate2 cert = null;

            if (System.IO.File.Exists(certFile))
            {
                cert = new X509Certificate2(certFile, certPassword);
            }
            else
            {
                X509Store store = new X509Store(storeName, storeLocation);
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                X509Certificate2Collection CertCol = store.Certificates;

                //foreach (X509Certificate2 c in CertCol)
                //{
                //    if (c.Subject.Contains(findValue.ToString()))
                //    {
                //        cert = c;
                //        break;
                //    }
                //}

                X509Certificate2Collection coll = store.Certificates.Find(findType, findValue.ToString(), false);

                //if (cert == null)
                //{
                //    throw new ArgumentException("Unable to locate certificate");
                //}
                if (coll.Count < 1)
                {
                    throw new ArgumentException("Unable to locate certificate");
                }
                cert = coll[0];
                store.Close();
            }

            XmlElement signature = SigningHelper.SignDoc(doc, cert, response.ID);

            doc.DocumentElement.InsertBefore(signature,
                                             doc.DocumentElement.ChildNodes[1]);

            string responseStr = doc.OuterXml;

            byte[] base64EncodedBytes =
                Encoding.UTF8.GetBytes(responseStr);

            string returnValue = System.Convert.ToBase64String(
                base64EncodedBytes);

            return(returnValue);
        }
コード例 #12
0
ファイル: Authentication.cs プロジェクト: tcoffsite/SSO
        /// <REMARKS>
        /// AuthenticateSAMLResponse supports SP-Initiated and IDP-Initated, POST
        /// Does not pass specific SAML status values back to the caller; caller sends SAML Failed or Success status
        /// </REMARKS>
        internal static bool AuthenticateSamlResponse()
        {
            //Authenticated SAML Response will have the SAML token, transform the token into PTS Credential, create the principal, authenticated=true, create the SP cookie
            string parameterSamlResponse = HttpContext.Current.Request.Form[Helpers.Names.HttpParameterResponseSaml];

            if (string.IsNullOrEmpty(parameterSamlResponse))
            {
                return(HttpContext.Current.Request.IsAuthenticated);
            }

            //Validate SAML Response
            string      decodedSamlResponse = Helpers.Helper.Utf8Base64DecodeString(parameterSamlResponse);
            XmlDocument xmlResponse         = Helpers.Helper.ReadyXmlDocument;

            xmlResponse.LoadXml(decodedSamlResponse);

            ResponseType response     = Helpers.Helper.DeserializeXmlDocumentToType <ResponseType>(xmlResponse);
            XmlElement   xmlSignature = Saml.Helper.SelectXMLElement(xmlResponse, Names.SAMLNamesElementAssertionSignature, SignedXml.XmlDsigNamespaceUrl);

            //SAML Response objects are Federated;  if the response is verified then the subject is trusted (authenticated)
            //However, from Federated IDPs the assertions must match the PTS Endpoint Claim set registered in SQL
            if (xmlSignature == null || !Saml.Helper.VerifySignedXMLElement(xmlResponse.DocumentElement, xmlSignature))
            {
                return(HttpContext.Current.Request.IsAuthenticated);
            }

            //From SAML Response assertions and RelayState, validate the user and build the PTS authenticated credential
            AssertionType          assertion     = response.Items.Where(t => t.GetType().FullName == typeof(AssertionType).FullName)?.First() as AssertionType;
            NameIDType             nameId        = assertion.Subject.Items.Where(t => t.GetType().FullName == typeof(NameIDType).FullName)?.First() as NameIDType;
            AttributeStatementType statement     = assertion?.Items.Where(t => t.GetType().FullName == typeof(AttributeStatementType).FullName)?.First() as AttributeStatementType;
            List <AttributeType>   attributeList = statement?.Items.Select(a => (AttributeType)a)?.ToList();
            string subjectNameId = nameId?.Value;

            //Response message not expired; eliminates replay attack
            if (DateTime.Now >= assertion.Conditions.NotOnOrAfter)
            {
                return(HttpContext.Current.Request.IsAuthenticated);
            }
            Credential credential = new Credential {
                EntityId = subjectNameId, ClaimsId = assertion.Issuer.Value, Refresh = true
            };

            //Claim set valid; eliminate man-in-the-middle attack
            if (!AuthenticateSamlAssertion(attributeList, ref credential))
            {
                return(HttpContext.Current.Request.IsAuthenticated);
            }

            XmlDocument xmlCredential = Helpers.Helper.SerializeTypeToXmlDocument(credential);

            //Deflate (W3C) and Encrypt (RSA) the PTS SSO XML Document credential...
            string credentialDeflatedEncrypted = Helpers.Helper.XmlDocumentDeflateEncrypt(xmlCredential);

            //Create Authenticated Principal from PTS Credential
            ClaimsIdentity claimsIdentity = new ClaimsIdentity(
                new GenericIdentity(credential.Email, Helpers.Names.PrincipalType),
                credential.Claims.Select(c => new System.Security.Claims.Claim($"{c.Name}:{c.FriendlyName}", c.Value, c.NameFormat, c.EntityId))
                //Inserting a Generic Identity into the Claims Identity makes the User context both claim and role aware...
                );

            HttpContext.Current.User = new GenericPrincipal(claimsIdentity, credential.Roles.Select(r => r.Name).ToArray());

            //Set PTS Authentication Session cookie; note the IIS Pipeline cache is not available in the application authenticaiton event
            //The only other cache choice for user credentials is another call to SQL Server with each IIS Pipeline request
            HttpContext.Current.Response.Cookies.Add(new HttpCookie(Helpers.Names.HttpCookiePtsSso)
            {
                //IDP root session cookie, not persistant, not client script accessible, value is segmented, encrypted and defalted (W3C/RSA compliant)
                Expires = DateTime.MinValue, HttpOnly = true, Path = Helpers.Names.PathRoot, Value = credentialDeflatedEncrypted
            });

            return(HttpContext.Current.Request.IsAuthenticated);
        }
コード例 #13
0
        /// <summary>
        /// Creates a Version 1.1 Saml Assertion
        /// </summary>
        /// <param name="issuer">Issuer</param>
        /// <param name="subject">Subject</param>
        /// <param name="attributes">Attributes</param>
        /// <returns>returns a Version 1.1 Saml Assertion</returns>
        private static AssertionType CreateSamlAssertion(string issuer, string recipient, string domain, string subject, Dictionary <string, string> attributes)
        {
            // Here we create some SAML assertion with ID and Issuer name.
            AssertionType assertion = new AssertionType();

            assertion.ID = "_" + Guid.NewGuid().ToString();

            NameIDType issuerForAssertion = new NameIDType();

            issuerForAssertion.Value = issuer.Trim();

            assertion.Issuer  = issuerForAssertion;
            assertion.Version = "2.0";

            assertion.IssueInstant = System.DateTime.UtcNow;

            //Not before, not after conditions
            ConditionsType conditions = new ConditionsType();

            conditions.NotBefore             = DateTime.UtcNow;
            conditions.NotBeforeSpecified    = true;
            conditions.NotOnOrAfter          = DateTime.UtcNow.AddMinutes(5);
            conditions.NotOnOrAfterSpecified = true;

            AudienceRestrictionType audienceRestriction = new AudienceRestrictionType();

            audienceRestriction.Audience = new string[] { domain.Trim() };

            conditions.Items = new ConditionAbstractType[] { audienceRestriction };

            //Name Identifier to be used in Saml Subject
            NameIDType nameIdentifier = new NameIDType();

            nameIdentifier.NameQualifier = domain.Trim();
            nameIdentifier.Value         = subject.Trim();

            SubjectConfirmationType     subjectConfirmation     = new SubjectConfirmationType();
            SubjectConfirmationDataType subjectConfirmationData = new SubjectConfirmationDataType();

            subjectConfirmation.Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer";
            subjectConfirmation.SubjectConfirmationData = subjectConfirmationData;
            //
            // Create some SAML subject.
            SubjectType samlSubject = new SubjectType();

            AttributeStatementType attrStatement = new AttributeStatementType();
            AuthnStatementType     authStatement = new AuthnStatementType();

            authStatement.AuthnInstant = DateTime.UtcNow;
            AuthnContextType context = new AuthnContextType();

            context.ItemsElementName   = new ItemsChoiceType5[] { ItemsChoiceType5.AuthnContextClassRef };
            context.Items              = new object[] { "AuthnContextClassRef" };
            authStatement.AuthnContext = context;

            samlSubject.Items = new object[] { nameIdentifier, subjectConfirmation };

            assertion.Subject = samlSubject;

            IPHostEntry ipEntry =
                Dns.GetHostEntry(System.Environment.MachineName);

            SubjectLocalityType subjectLocality = new SubjectLocalityType();

            subjectLocality.Address = ipEntry.AddressList[0].ToString();

            attrStatement.Items = new AttributeType[attributes.Count];
            int i = 0;

            // Create userName SAML attributes.
            foreach (KeyValuePair <string, string> attribute in attributes)
            {
                AttributeType attr = new AttributeType();
                attr.Name              = attribute.Key;
                attr.NameFormat        = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic";
                attr.AttributeValue    = new object[] { attribute.Value };
                attrStatement.Items[i] = attr;
                i++;
            }
            assertion.Conditions = conditions;

            assertion.Items = new StatementAbstractType[] { authStatement, attrStatement };

            return(assertion);
        }
コード例 #14
0
        /// <summary>
        /// Creates a SAML 2.0 Assertion Segment for a Response
        /// Simple implmenetation assuming a list of string key and value pairs
        /// </summary>
        /// <param name="Issuer"></param>
        /// <param name="AssertionExpirationMinutes"></param>
        /// <param name="Audience"></param>
        /// <param name="Subject"></param>
        /// <param name="Recipient"></param>
        /// <param name="Attributes">Dictionary of string key, string value pairs</param>
        /// <returns>Assertion to sign and include in Response</returns>
        private static AssertionType CreateSAML20Assertion(string Issuer,
                                                           int AssertionExpirationMinutes,
                                                           string Audience,
                                                           string Subject,
                                                           string Recipient,
                                                           Dictionary <string, string> Attributes)
        {
            AssertionType NewAssertion = new AssertionType()
            {
                Version      = "2.0",
                IssueInstant = DateTime.Now,//DateTime.UtcNow,
                ID           = "_" + System.Guid.NewGuid().ToString()
            };

            // Create Issuer
            NewAssertion.Issuer = new NameIDType()
            {
                Value = Issuer.Trim()
            };

            // Create Assertion Subject
            SubjectType subject = new SubjectType();
            NameIDType  subjectNameIdentifier = new NameIDType()
            {
                Value = Subject.Trim(), Format = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
            };
            SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType()
            {
                Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer", SubjectConfirmationData = new SubjectConfirmationDataType()
                {
                    NotOnOrAfter = DateTime.Now.AddMinutes(AssertionExpirationMinutes), Recipient = Recipient
                }
            };                                                                                                                                                                                                                                                                                           //{ NotOnOrAfter = DateTime.UtcNow.AddMinutes(AssertionExpirationMinutes), Recipient = Recipient } };

            subject.Items        = new object[] { subjectNameIdentifier, subjectConfirmation };
            NewAssertion.Subject = subject;

            // Create Assertion Conditions
            ConditionsType conditions = new ConditionsType();

            conditions.NotBefore             = DateTime.Now;                                        //DateTime.UtcNow;
            conditions.NotBeforeSpecified    = true;
            conditions.NotOnOrAfter          = DateTime.Now.AddMinutes(AssertionExpirationMinutes); //DateTime.UtcNow.AddMinutes(AssertionExpirationMinutes);
            conditions.NotOnOrAfterSpecified = true;
            conditions.Items = new ConditionAbstractType[] { new AudienceRestrictionType()
                                                             {
                                                                 Audience = new string[] { Audience.Trim() }
                                                             } };
            NewAssertion.Conditions = conditions;

            // Add AuthnStatement and Attributes as Items
            AuthnStatementType authStatement = new AuthnStatementType()
            {
                AuthnInstant = DateTime.Now, SessionIndex = NewAssertion.ID
            };                                                                                                                           //{ AuthnInstant = DateTime.UtcNow, SessionIndex = NewAssertion.ID };
            AuthnContextType context = new AuthnContextType();

            context.ItemsElementName   = new ItemsChoiceType5[] { ItemsChoiceType5.AuthnContextClassRef };
            context.Items              = new object[] { "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified" };
            authStatement.AuthnContext = context;

            AttributeStatementType attributeStatement = new AttributeStatementType();

            attributeStatement.Items = new AttributeType[Attributes.Count];
            int i = 0;

            foreach (KeyValuePair <string, string> attribute in Attributes)
            {
                attributeStatement.Items[i] = new AttributeType()
                {
                    Name           = attribute.Key,
                    AttributeValue = new object[] { attribute.Value },
                    NameFormat     = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
                };
                i++;
            }

            NewAssertion.Items = new StatementAbstractType[] { authStatement, attributeStatement };

            return(NewAssertion);
        }
コード例 #15
0
ファイル: Saml2Service.cs プロジェクト: tim-klug/Saml2Core
        /// <summary>
        /// Creates the logout request.
        /// The "LogoutRequest" message MUST be signed if the HTTP POST or Redirect binding is used.
        /// Logout request MUST be signed according to http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf Sect 4.4.3.1
        /// </summary>
        /// <param name="options">The options.</param>
        /// <param name="logoutRequestId">The logout request identifier.</param>
        /// <param name="sessionIndex">Index of the session.</param>
        /// <param name="nameId">The name identifier.</param>
        /// <param name="relayState">State of the relay.</param>
        /// <param name="sendSignoutTo">The send signout to.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException">Signing key must be an instance of either RSA or DSA.</exception>
        public string CreateLogoutRequest(Saml2Options options, string logoutRequestId, string sessionIndex, string nameId, string relayState, string sendSignoutTo)
        {
            NameIDType entityID = new NameIDType()
            {
                Value = options.ServiceProvider.EntityId
            };

            var singleLogoutService = options.Configuration.SingleLogoutServices.FirstOrDefault(x => x.Binding == options.SingleLogoutServiceProtocolBinding);

            LogoutRequest logoutRequest = new LogoutRequest()
            {
                ID           = logoutRequestId,
                Issuer       = entityID,
                Version      = Saml2Constants.Version,
                Reason       = Saml2Constants.Reasons.User,
                SessionIndex = new string[] { sessionIndex },
                Destination  = singleLogoutService.Location.ToString(),
                IssueInstant = DateTime.UtcNow,
                Item         = new NameIDType()
                {
                    Format          = options.NameIDType.Format,
                    NameQualifier   = options.NameIDType.NameQualifier,
                    SPProvidedID    = options.NameIDType.SPProvidedID,
                    SPNameQualifier = options.NameIDType.SPNameQualifier,
                    Value           = options.NameIDType.Value
                }
            };

            string singleLogoutUrl = options.Configuration.SingleLogoutServices.FirstOrDefault().Location;

            //serialize AuthnRequest to xml string
            string        xmlTemplate   = string.Empty;
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(LogoutRequest));

            using (MemoryStream memStm = new MemoryStream())
            {
                xmlSerializer.Serialize(memStm, logoutRequest);
                memStm.Position = 0;
                xmlTemplate     = new StreamReader(memStm).ReadToEnd();
            }

            //create xml document from string
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(xmlTemplate);
            xmlDoc.PreserveWhitespace = false;
            string request = xmlDoc.OuterXml;

            var result = new StringBuilder();

            result.AddMessageParameter(request, null);
            result.AddRelayState(request, relayState);
            if (options.hasCertificate)
            {
                X509Certificate2    spCertificate    = GetServiceProviderCertficate(options);
                string              hashingAlgorithm = options.Configuration.Signature.SignedInfo.SignatureMethod;
                AsymmetricAlgorithm spPrivateKey     = spCertificate.PrivateKey;
                // Check if the key is of a supported type. [SAMLBind] sect. 3.4.4.1 specifies this.
                if (!(spPrivateKey is RSA || spPrivateKey is DSA || spPrivateKey == null))
                {
                    throw new ArgumentException("Signing key must be an instance of either RSA or DSA.");
                }
                AddSignature(result, spPrivateKey, hashingAlgorithm, options.ServiceProvider.HashAlgorithm);
            }
            return($"{singleLogoutUrl}?{result}");
        }
コード例 #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="UUID"></param>
        /// <param name="Destination"></param>
        /// <param name="ConsumerServiceURL"></param>
        /// <param name="certFile"></param>
        /// <param name="certPassword"></param>
        /// <param name="storeLocation"></param>
        /// <param name="storeName"></param>
        /// <param name="findType"></param>
        /// <param name="findValue"></param>
        /// <param name="signatureType"></param>
        /// <returns></returns>
        public static string BuildPostSamlRequest(string UUID, string Destination, string ConsumerServiceURL, int SecurityLevel,
                                                  string certFile, string certPassword,
                                                  StoreLocation storeLocation, StoreName storeName,
                                                  X509FindType findType, object findValue, SigningHelper.SignatureType signatureType, string IdentityProvider, int Enviroment)
        {
            AuthnRequestType MyRequest = new AuthnRequestType
            {
                ID      = UUID,
                Version = "2.0"
            };
            DateTime now         = DateTime.UtcNow;
            DateTime after       = now.AddMinutes(10);
            string   nowString   = String.Empty;
            string   afterString = String.Empty;

            if (IdentityProvider.Contains("sielte"))
            {
                // SIELTE
                nowString   = now.AddMinutes(-2).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'");
                afterString = after.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'");
            }
            else
            {
                // POSTE - TIM - INFOCERT
                nowString   = now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
                afterString = after.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
            }
            MyRequest.IssueInstant = nowString;
            if (SecurityLevel > 1)
            {
                MyRequest.ForceAuthn          = true;
                MyRequest.ForceAuthnSpecified = true;
            }
            MyRequest.Destination = Destination;
            MyRequest.AssertionConsumerServiceIndex           = (ushort)Enviroment;
            MyRequest.AssertionConsumerServiceIndexSpecified  = true;
            MyRequest.AttributeConsumingServiceIndex          = 1;
            MyRequest.AttributeConsumingServiceIndexSpecified = true;

            NameIDType IssuerForRequest = new NameIDType
            {
                Value         = ConsumerServiceURL.Trim(),
                Format        = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity",
                NameQualifier = ConsumerServiceURL
            };

            MyRequest.Issuer = IssuerForRequest;

            NameIDPolicyType NameIdPolicyForRequest = new NameIDPolicyType
            {
                Format               = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
                AllowCreate          = true,
                AllowCreateSpecified = true
            };

            MyRequest.NameIDPolicy = NameIdPolicyForRequest;

            ConditionsType Conditional = new ConditionsType();

            if (IdentityProvider.Contains("sielte"))
            {
                // SIELTE
                Conditional.NotBefore = nowString;
            }
            else
            {
                // POSTE - TIM - INFOCERT
                Conditional.NotBefore = now.AddMinutes(-2).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
            }

            Conditional.NotBeforeSpecified    = true;
            Conditional.NotOnOrAfter          = afterString;
            Conditional.NotOnOrAfterSpecified = true;
            MyRequest.Conditions = Conditional;

            RequestedAuthnContextType RequestedAuthn = new RequestedAuthnContextType
            {
                Comparison          = AuthnContextComparisonType.minimum,
                ComparisonSpecified = true,
                ItemsElementName    = new ItemsChoiceType7[] { ItemsChoiceType7.AuthnContextClassRef },
                Items = new string[] { "https://www.spid.gov.it/SpidL" + SecurityLevel.ToString() }
            };

            MyRequest.RequestedAuthnContext = RequestedAuthn;

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol");
            //ns.Add("saml2", "urn:oasis:names:tc:SAML:2.0:assertion");

            XmlSerializer responseSerializer = new XmlSerializer(MyRequest.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings
            {
                OmitXmlDeclaration = true,
                Indent             = true,
                Encoding           = Encoding.UTF8
            };

            XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings);

            responseSerializer.Serialize(responseWriter, MyRequest, ns);
            responseWriter.Close();

            string samlString = string.Empty;

            samlString = stringWriter.ToString();

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);
            X509Certificate2 cert = null;

            if (System.IO.File.Exists(certFile))
            {
                cert = new X509Certificate2(certFile, certPassword);
            }
            else
            {
                X509Store store = new X509Store(storeName, storeLocation);
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                X509Certificate2Collection CertCol = store.Certificates;

                X509Certificate2Collection coll = store.Certificates.Find(findType, findValue.ToString(), false);

                if (coll.Count < 1)
                {
                    throw new ArgumentException("Unable to locate certificate");
                }
                cert = coll[0];
                store.Close();
            }

            XmlElement signature = SigningHelper.SignDoc(doc, cert, UUID);

            doc.DocumentElement.InsertBefore(signature, doc.DocumentElement.ChildNodes[1]);

            string responseStr = doc.OuterXml;

            //byte[] base64EncodedBytes =
            //    Encoding.UTF8.GetBytes(responseStr);

            //string returnValue = System.Convert.ToBase64String(
            //    base64EncodedBytes);

            return("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + responseStr);
        }
コード例 #17
0
ファイル: Login.cs プロジェクト: rafysanchez/SME-autenticador
        public new void ProcessRequest(HttpContext context)
        {
            try
            {
                // ***** RESPONSE *****
                if (!String.IsNullOrEmpty(context.Request[HttpBindingConstants.SAMLResponse]))
                {
                    // Recupera Response
                    string      samlresponse = context.Request[HttpBindingConstants.SAMLResponse];
                    XmlDocument doc          = new XmlDocument();
                    doc.PreserveWhitespace = true;
                    doc.LoadXml(samlresponse);

                    // Verifica Signature do Response
                    if (XmlSignatureUtils.VerifySignature(doc))
                    {
                        SAMLResponse = SAMLUtility.DeserializeFromXmlString <ResponseType>(doc.InnerXml);
                        if (SAMLResponse.Items.Length > 0)
                        {
                            for (int i = 0; i < SAMLResponse.Items.Length; i++)
                            {
                                if (SAMLResponse.Items[i] is AssertionType)
                                {
                                    NameIDType    nameID    = null;
                                    AssertionType assertion = (AssertionType)SAMLResponse.Items[i];
                                    for (int j = 0; j < assertion.Subject.Items.Length; j++)
                                    {
                                        if (assertion.Subject.Items[j] is NameIDType)
                                        {
                                            nameID = (NameIDType)assertion.Subject.Items[j];
                                        }
                                    }
                                    if (nameID != null)
                                    {
                                        SignHelper.AutenticarUsuarioDaRespostaDoSaml(nameID.Value);
                                    }
                                }

                                // Armazena dados do sistema emissor do Request
                                // em Cookie de sistemas autenticados
                                AddSAMLCookie(context);
                            }
                        }
                        context.Response.Redirect(HttpUtility.UrlDecode(context.Request[HttpBindingConstants.RelayState]), false);
                    }
                    else
                    {
                        throw new ValidationException("Não foi possível encontrar assinatura.");
                    }
                }
                // ***** REQUEST *****
                else if (!String.IsNullOrEmpty(context.Request[HttpBindingConstants.SAMLRequest]))
                {
                    throw new NotImplementedException();
                }
                else
                {
                    // Carrega as configurações do ServiceProvider
                    ServiceProvider         config = ServiceProvider.GetConfig();
                    ServiceProviderEndpoint spend  = SAMLUtility.GetServiceProviderEndpoint(config.ServiceEndpoint, SAMLTypeSSO.signon);

                    // Verifica configuração do ServiceProvider para signon
                    if (spend == null)
                    {
                        throw new ValidationException("Não foi possível encontrar as configurações do ServiceProvider para signon.");
                    }

                    // Verifica se usuário está autenticado, caso não envia um Resquest solicitando autenticação
                    if (!UsuarioWebIsValid())
                    {
                        SAMLRequest        = new SAMLAuthnRequest();
                        SAMLRequest.Issuer = config.id;
                        SAMLRequest.AssertionConsumerServiceURL = context.Request.Url.AbsoluteUri;

                        HttpRedirectBinding binding = new HttpRedirectBinding(SAMLRequest, spend.localpath);
                        binding.SendRequest(context, spend.redirectUrl);
                    }
                    else
                    {
                        HttpContext.Current.Response.Redirect(spend.localpath, false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                    }
                }
            }
            catch (ValidationException ex)
            {
                ErrorMessage(ex.Message);
            }
            catch (Exception ex)
            {
                ApplicationWEB._GravaErro(ex);

                ErrorMessage("Não foi possível atender a solicitação.");
            }
        }
コード例 #18
0
ファイル: TestSaml.cs プロジェクト: link-nv/linkid-sdk-dotnet
        public void TestAuthnRequest()
        {
            AuthnRequestType authnRequest = new AuthnRequestType();

            authnRequest.ID = "test-id";
            authnRequest.AssertionConsumerServiceURL = "http://test.assertion.consumer";
            authnRequest.Destination     = "http://destination";
            authnRequest.ForceAuthn      = true;
            authnRequest.ProtocolBinding = "urn:test:protocol:binding";
            authnRequest.Version         = "2.0";
            authnRequest.IssueInstant    = DateTime.Now.ToUniversalTime();

            NameIDType issuer = new NameIDType();

            issuer.Value        = "test-issuer";
            authnRequest.Issuer = issuer;

            NameIDPolicyType nameIdPolicy = new NameIDPolicyType();

            nameIdPolicy.AllowCreate          = true;
            nameIdPolicy.AllowCreateSpecified = true;
            authnRequest.NameIDPolicy         = nameIdPolicy;

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
            ns.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
            //ns.Add("ds", "http://www.w3.org/2000/09/xmldsig#");

            XmlRootAttribute xRoot = new XmlRootAttribute();

            xRoot.ElementName = "AuthnRequest";
            xRoot.Namespace   = "urn:oasis:names:tc:SAML:2.0:protocol";
            XmlSerializer serializer    = new XmlSerializer(typeof(AuthnRequestType), xRoot);
            MemoryStream  memoryStream  = new MemoryStream();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

            serializer.Serialize(xmlTextWriter, authnRequest, ns);
            memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
            string result = new UTF8Encoding().GetString(memoryStream.ToArray());

            Console.WriteLine("result: " + result);

            XmlDocument document = new XmlDocument();

            memoryStream.Seek(0, SeekOrigin.Begin);
            document.Load(memoryStream);
            String xmlString = document.OuterXml;

            Console.WriteLine("DOM result: " + xmlString);

            RSACryptoServiceProvider Key = new RSACryptoServiceProvider();

            SignedXml signedXml = new SignedXml(document);

            signedXml.SigningKey = Key;
            Signature signature = signedXml.Signature;

            signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            Reference reference = new Reference("#" + authnRequest.ID);
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

            reference.AddTransform(env);
            XmlDsigExcC14NTransform excC14NTransform = new XmlDsigExcC14NTransform("ds saml samlp");

            reference.AddTransform(excC14NTransform);
            signature.SignedInfo.AddReference(reference);

            signedXml.ComputeSignature();

            XmlElement xmlDigitalSignature = signedXml.GetXml();

            document.DocumentElement.AppendChild(document.ImportNode(xmlDigitalSignature, true));

            result = document.OuterXml;
            Console.WriteLine("result: " + result);

            XmlTextWriter xmltw = new XmlTextWriter(TestConstants.workDir + "\\test.xml", new UTF8Encoding(false));

            document.WriteTo(xmltw);
            xmltw.Close();
        }
コード例 #19
0
        /// <summary>
        /// Generates a SAML v2.0 Authentication Request with HTTP Browser Post Binding.
        /// The return string containing the request is NOT Base64 encoded.
        /// </summary>
        /// <param name="linkIDContext">the linkID authentication/payment configuration</param>
        /// <returns>SAML request</returns>
        public static AuthnRequestType generateAuthnRequest(LinkIDAuthenticationContext linkIDContext)
        {
            AuthnRequestType authnRequest = new AuthnRequestType();

            authnRequest.ForceAuthn   = true;
            authnRequest.ID           = Guid.NewGuid().ToString();
            authnRequest.Version      = "2.0";
            authnRequest.IssueInstant = DateTime.UtcNow;

            NameIDType issuer = new NameIDType();

            issuer.Value        = linkIDContext.applicationName;
            authnRequest.Issuer = issuer;

            NameIDPolicyType nameIdPolicy = new NameIDPolicyType();

            nameIdPolicy.AllowCreate          = true;
            nameIdPolicy.AllowCreateSpecified = true;
            authnRequest.NameIDPolicy         = nameIdPolicy;

            Dictionary <string, string> deviceContextMap = linkIDContext.getDeviceContextMap();
            DeviceContextType           deviceContext    = null;

            if (null != deviceContextMap && deviceContextMap.Count > 0)
            {
                deviceContext = new DeviceContextType();
                List <AttributeType> attributes = new List <AttributeType>();
                foreach (string deviceContextKey in deviceContextMap.Keys)
                {
                    string        deviceContextValue = deviceContextMap[deviceContextKey];
                    AttributeType attribute          = new AttributeType();
                    attribute.Name           = deviceContextKey;
                    attribute.AttributeValue = new object[] { deviceContextValue };
                    attributes.Add(attribute);
                    deviceContext.Items = attributes.ToArray();
                }
            }
            SubjectAttributesType subjectAttributes = null;

            if (null != linkIDContext.attributeSuggestions && linkIDContext.attributeSuggestions.Count > 0)
            {
                subjectAttributes = new SubjectAttributesType();
                List <AttributeType> attributes = new List <AttributeType>();
                foreach (string attributeName in linkIDContext.attributeSuggestions.Keys)
                {
                    List <object> values = linkIDContext.attributeSuggestions[attributeName];

                    AttributeType attribute = new AttributeType();
                    attribute.Name           = attributeName;
                    attribute.AttributeValue = values.ToArray();
                    attributes.Add(attribute);
                    subjectAttributes.Items = attributes.ToArray();
                }
            }

            PaymentContextType paymentContextType = null;

            if (null != linkIDContext.paymentContext)
            {
                Dictionary <String, String> paymentContextDict = linkIDContext.paymentContext.toDictionary();
                paymentContextType = new PaymentContextType();
                List <AttributeType> attributes = new List <AttributeType>();
                foreach (string paymentContextKey in paymentContextDict.Keys)
                {
                    string        value     = paymentContextDict[paymentContextKey];
                    AttributeType attribute = new AttributeType();
                    attribute.Name           = paymentContextKey;
                    attribute.AttributeValue = new object[] { value };
                    attributes.Add(attribute);
                    paymentContextType.Items = attributes.ToArray();
                }
            }

            CallbackType callbackType = null;

            if (null != linkIDContext.callback)
            {
                Dictionary <String, String> callbackDict = linkIDContext.callback.toDictionary();
                callbackType = new CallbackType();
                List <AttributeType> attributes = new List <AttributeType>();
                foreach (string callbackKey in callbackDict.Keys)
                {
                    string        value     = callbackDict[callbackKey];
                    AttributeType attribute = new AttributeType();
                    attribute.Name           = callbackKey;
                    attribute.AttributeValue = new object[] { value };
                    attributes.Add(attribute);
                    callbackType.Items = attributes.ToArray();
                }
            }


            if (null != deviceContext || null != subjectAttributes || null != paymentContextType || null != callbackType)
            {
                ExtensionsType    extensions     = new ExtensionsType();
                List <XmlElement> extensionsList = new List <XmlElement>();
                if (null != subjectAttributes)
                {
                    extensionsList.Add(toXmlElement(subjectAttributes));
                }
                if (null != deviceContext)
                {
                    extensionsList.Add(toXmlElement(deviceContext));
                }
                if (null != paymentContextType)
                {
                    extensionsList.Add(toXmlElement(paymentContextType));
                }
                if (null != callbackType)
                {
                    extensionsList.Add(toXmlElement(callbackType));
                }
                extensions.Any          = extensionsList.ToArray();
                authnRequest.Extensions = extensions;
            }

            return(authnRequest);
        }
コード例 #20
0
ファイル: SAMLEngine.cs プロジェクト: jcaubin/claveOwin
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private XmlDocument GenerateResponseMetadata(SAMLContext context, string id)
        {
            DateTime      now    = DateTime.UtcNow;
            MemoryStream  stream = new MemoryStream();
            StreamReader  reader;
            XmlTextReader xmlReader;

            ResponseType response = new ResponseType();

            response.ID           = id;
            response.InResponseTo = context.RequestID;
            response.Version      = SAMLConstants.SAML_VERSION;
            response.IssueInstant = now;

            response.Destination   = context.AssertionConsumer;
            response.Consent       = SAMLConstants.CONSENT;
            response.Issuer        = new NameIDType();
            response.Issuer.Value  = thisIssuer;
            response.Issuer.Format = SAMLConstants.ThisIssuerFormat;

            response.Status                  = new StatusType();
            response.Status.StatusCode       = new StatusCodeType();
            response.Status.StatusCode.Value = SAMLConstants.StatusCode.statusCode[context.StatusCode];
            if (context.StatusCode != SAMLConstants.StatusCode.SUCCESS)
            {
                response.Status.StatusCode.StatusCode       = new StatusCodeType();
                response.Status.StatusCode.StatusCode.Value =
                    SAMLConstants.StatusCode.statusCode[context.SubStatusCode];
                response.Status.StatusMessage = context.StatusMessage;
            }

            AssertionType assertion = new AssertionType();

            assertion.ID           = "_" + Guid.NewGuid().ToString();
            assertion.Version      = SAMLConstants.SAML_VERSION;
            assertion.IssueInstant = now;

            assertion.Issuer        = new NameIDType();
            assertion.Issuer.Value  = thisIssuer;
            assertion.Issuer.Format = SAMLConstants.ThisIssuerFormat;

            assertion.Subject = new SubjectType();
            NameIDType nameId = new NameIDType();

            nameId.Format = "urn:oasis:names:tc:SAML:1.1:nameid- format:unspecified";
            //nameId.NameQualifier = "http://C-PEPS.gov.xx";
            nameId.Value = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified";

            SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType();

            subjectConfirmation.Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer";
            subjectConfirmation.SubjectConfirmationData              = new SubjectConfirmationDataType();
            subjectConfirmation.SubjectConfirmationData.Address      = context.SubjectAddress;
            subjectConfirmation.SubjectConfirmationData.InResponseTo = context.RequestID;
            //subjectConfirmation.SubjectConfirmationData.NotBeforeString = "2010-02-03T17:06:18.099Z";
            subjectConfirmation.SubjectConfirmationData.NotOnOrAfterString =
                String.Format("{0:yyyy-MM-ddTHH:mm:ssZ}", now.AddMinutes(validTimeframe));
            subjectConfirmation.SubjectConfirmationData.Recipient = context.Issuer;
            assertion.Subject.Items = new object[] { nameId, subjectConfirmation };

            assertion.Conditions = new ConditionsType();
            assertion.Conditions.NotBeforeString    = String.Format("{0:yyyy-MM-ddTHH:mm:ssZ}", now);
            assertion.Conditions.NotOnOrAfterString =
                String.Format("{0:yyyy-MM-ddTHH:mm:ssZ}", now.AddMinutes(validTimeframe));

            AudienceRestrictionType audience = new AudienceRestrictionType();

            audience.Audience          = new string[] { context.Issuer }; // FIXME
            assertion.Conditions.Items = new ConditionAbstractType[] { audience, new OneTimeUseType() };

            AuthnStatementType authnStatement = new AuthnStatementType();

            authnStatement.AuthnInstant = now;
            authnStatement.AuthnContext = new AuthnContextType();

            List <AttributeElement> attributes = context.GetAttributes();

            object[]      attributesDescription = new AttributeType[attributes.Count];
            AttributeType attr;
            XmlAttribute  statusAttr;
            int           i = 0;

            foreach (AttributeElement element in attributes)
            {
                attr            = new AttributeType();
                attr.Name       = element.AttrName;
                attr.NameFormat = element.NameFormat;
                if (context.StatusCode == SAMLConstants.StatusCode.SUCCESS)
                {
                    if (element.AttrStatus == SAMLConstants.AttributeStatus.AVAILABLE &&
                        element.AttrValue != null)
                    {
                        attr.AttributeValue = new object[] { element.AttrValue }
                    }
                    ;
                    if (element.AttrStatus >= 0)
                    {
                        statusAttr = new XmlDocument().
                                     CreateAttribute(SAMLConstants.ATTRIBUTE_STATUS_STR, SAMLConstants.NS_STORK_ASSER);
                        statusAttr.Value = element.Status;
                        attr.AnyAttr     = new XmlAttribute[] { statusAttr };
                    }
                }
                attributesDescription[i++] = attr;
            }

            AttributeStatementType attributeStatement = new AttributeStatementType();

            attributeStatement.Items = attributesDescription;
            assertion.Items          = new StatementAbstractType[] { authnStatement, attributeStatement };
            response.Items           = new object[] { assertion };

            stream = new MemoryStream();
            Serialize(response, stream);

            reader = new StreamReader(stream);
            stream.Seek(0, SeekOrigin.Begin);
            xmlReader = new XmlTextReader(new StringReader(reader.ReadToEnd()));
            return(Deserialize <XmlDocument>(xmlReader));
        }
コード例 #21
0
ファイル: Saml2Service.cs プロジェクト: tim-klug/Saml2Core
        /// <summary>
        /// Creates the authn request.
        /// </summary>
        /// <param name="options">The options.</param>
        /// <param name="authnRequestId">The authn request identifier.</param>
        /// <param name="relayState">State of the relay.</param>
        /// <param name="assertionConsumerServiceUrl">The assertion consumer service URL.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException">Signing key must be an instance of either RSA or DSA.</exception>
        public string CreateAuthnRequest(Saml2Options options, string authnRequestId, string relayState, string assertionConsumerServiceUrl)
        {
            NameIDType entityID = new NameIDType()
            {
                Value = options.ServiceProvider.EntityId
            };

            var singleSignOnService        = options.Configuration.SingleSignOnServices.FirstOrDefault(x => x.Binding == options.AssertionConsumerServiceProtocolBinding);
            X509Certificate2 spCertificate = GetServiceProviderCertficate(options);

            AuthnRequest authnRequest = new AuthnRequest()
            {
                ID                  = authnRequestId,
                Issuer              = entityID,
                Version             = Saml2Constants.Version,
                ForceAuthn          = options.ForceAuthn,
                ForceAuthnSpecified = true,
                IsPassive           = options.IsPassive,
                IsPassiveSpecified  = true,
                NameIDPolicy        = new NameIDPolicyType()
                {
                    Format               = options.NameIDType.Format,
                    SPNameQualifier      = options.NameIDType.SPNameQualifier,
                    AllowCreate          = true,
                    AllowCreateSpecified = true
                },
                Destination                 = singleSignOnService.Location.ToString(),
                ProtocolBinding             = singleSignOnService.Binding.ToString(),
                IssueInstant                = DateTime.UtcNow,
                AssertionConsumerServiceURL = assertionConsumerServiceUrl
            };

            string singleSignOnUrl = options.Configuration.SingleSignOnServices.FirstOrDefault().Location;

            //serialize AuthnRequest to xml string
            string        xmlTemplate   = string.Empty;
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(AuthnRequest));

            using (MemoryStream memStm = new MemoryStream())
            {
                xmlSerializer.Serialize(memStm, authnRequest);
                memStm.Position = 0;
                xmlTemplate     = new StreamReader(memStm).ReadToEnd();
            }

            //create xml document from string
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(xmlTemplate);
            xmlDoc.PreserveWhitespace = false;
            string request = xmlDoc.OuterXml;

            var result = new StringBuilder();

            result.AddMessageParameter(request, null);
            result.AddRelayState(request, relayState);
            if (options.ServiceProvider.X509Certificate2 != null)
            {
                AsymmetricAlgorithm spPrivateKey = spCertificate.PrivateKey;
                string hashingAlgorithm          = options.Configuration.Signature.SignedInfo.SignatureMethod;
                // Check if the key is of a supported type. [SAMLBind] sect. 3.4.4.1 specifies this.
                if (!(spPrivateKey is RSA || spPrivateKey is DSA || spPrivateKey == null))
                {
                    throw new ArgumentException("Signing key must be an instance of either RSA or DSA.");
                }

                AddSignature(result, spPrivateKey, hashingAlgorithm, options.ServiceProvider.HashAlgorithm);
            }
            return($"{singleSignOnUrl}?{result}");
        }
コード例 #22
0
        public void Deserialize(string samlResponse)
        {
            ResponseType response = new ResponseType();

            try
            {
                using (TextReader sr = new StringReader(samlResponse))
                {
                    var serializer = new System.Xml.Serialization.XmlSerializer(typeof(ResponseType));
                    response = (ResponseType)serializer.Deserialize(sr);

                    this.Version = response.Version;
                    this.UUID    = response.ID;
                    this.SPUID   = response.InResponseTo;
                    this.Issuer  = response.Issuer.Value;

                    switch (response.Status.StatusCode.Value)
                    {
                    case "urn:oasis:names:tc:SAML:2.0:status:Success":
                        this.RequestStatus = SamlRequestStatus.Success;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:Requester":
                        this.RequestStatus = SamlRequestStatus.RequesterError;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:Responder":
                        this.RequestStatus = SamlRequestStatus.ResponderError;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch":
                        this.RequestStatus = SamlRequestStatus.VersionMismatchError;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed":
                        this.RequestStatus = SamlRequestStatus.AuthnFailed;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue":
                        this.RequestStatus = SamlRequestStatus.InvalidAttrNameOrValue;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy":
                        this.RequestStatus = SamlRequestStatus.InvalidNameIDPolicy;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext":
                        this.RequestStatus = SamlRequestStatus.NoAuthnContext;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP":
                        this.RequestStatus = SamlRequestStatus.NoAvailableIDP;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:NoPassive":
                        this.RequestStatus = SamlRequestStatus.NoPassive;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP":
                        this.RequestStatus = SamlRequestStatus.NoSupportedIDP;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:PartialLogout":
                        this.RequestStatus = SamlRequestStatus.PartialLogout;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded":
                        this.RequestStatus = SamlRequestStatus.ProxyCountExceeded;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:RequestDenied":
                        this.RequestStatus = SamlRequestStatus.RequestDenied;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported":
                        this.RequestStatus = SamlRequestStatus.RequestUnsupported;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated":
                        this.RequestStatus = SamlRequestStatus.RequestVersionDeprecated;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh":
                        this.RequestStatus = SamlRequestStatus.RequestVersionTooHigh;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow":
                        this.RequestStatus = SamlRequestStatus.RequestVersionTooLow;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized":
                        this.RequestStatus = SamlRequestStatus.ResourceNotRecognized;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses":
                        this.RequestStatus = SamlRequestStatus.TooManyResponses;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile":
                        this.RequestStatus = SamlRequestStatus.UnknownAttrProfile;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal":
                        this.RequestStatus = SamlRequestStatus.UnknownPrincipal;
                        break;

                    case "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding":
                        this.RequestStatus = SamlRequestStatus.UnsupportedBinding;
                        break;

                    default:
                        this.RequestStatus = SamlRequestStatus.GenericError;
                        break;
                    }

                    if (this.RequestStatus == SamlRequestStatus.Success)
                    {
                        foreach (var item in response.Items)
                        {
                            if (item.GetType() == typeof(AssertionType))
                            {
                                AssertionType ass = (AssertionType)item;
                                this.SessionIdExpireDate = (ass.Conditions.NotOnOrAfter != null) ? ass.Conditions.NotOnOrAfter : DateTime.Now.AddMinutes(20);

                                foreach (var subitem in ass.Subject.Items)
                                {
                                    if (subitem.GetType() == typeof(NameIDType))
                                    {
                                        NameIDType nameId = (NameIDType)subitem;
                                        this.SubjectNameId = nameId.Value; //.Replace("SPID-","");
                                    }
                                }

                                foreach (var assItem in ass.Items)
                                {
                                    if (assItem.GetType() == typeof(AuthnStatementType))
                                    {
                                        AuthnStatementType authnStatement = (AuthnStatementType)assItem;
                                        this.SessionId           = authnStatement.SessionIndex;
                                        this.SessionIdExpireDate = (authnStatement.SessionNotOnOrAfterSpecified) ? authnStatement.SessionNotOnOrAfter : this.SessionIdExpireDate;
                                    }

                                    if (assItem.GetType() == typeof(AttributeStatementType))
                                    {
                                        AttributeStatementType statement = (AttributeStatementType)assItem;

                                        foreach (AttributeType attribute in statement.Items)
                                        {
                                            switch (attribute.Name)
                                            {
                                            case "spidCode":
                                                this.User.SpidCode = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "name":
                                                this.User.Name = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "familyName":
                                                this.User.FamilyName = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "gender":
                                                this.User.Gender = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "ivaCode":
                                                this.User.IvaCode = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "companyName":
                                                this.User.CompanyName = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "mobilePhone":
                                                this.User.MobilePhone = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "address":
                                                this.User.Address = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "fiscalNumber":
                                                this.User.FiscalNumber = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "dateOfBirth":
                                                this.User.DateOfBirth = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "placeOfBirth":
                                                this.User.PlaceOfBirth = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "countyOfBirth":
                                                this.User.CountyOfBirth = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "idCard":
                                                this.User.IdCard = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "registeredOffice":
                                                this.User.RegisteredOffice = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "email":
                                                this.User.Email = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "expirationDate":
                                                this.User.ExpirationDate = attribute.AttributeValue[0].ToString();
                                                break;

                                            case "digitalAddress":
                                                this.User.DigitalAddress = attribute.AttributeValue[0].ToString();
                                                break;

                                            default:
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //TODO Log
                throw ex;
            }
        }
コード例 #23
0
        /// <summary>
        /// GetPostSamlResponse - Returns a Base64 Encoded String with the SamlResponse in it.
        /// </summary>
        /// <param name="recipient">Recipient</param>
        /// <param name="issuer">Issuer</param>
        /// <param name="domain">Domain</param>
        /// <param name="subject">Subject</param>
        /// <param name="storeLocation">Certificate Store Location</param>
        /// <param name="storeName">Certificate Store Name</param>
        /// <param name="findType">Certificate Find Type</param>
        /// <param name="certLocation">Certificate Location</param>
        /// <param name="findValue">Certificate Find Value</param>
        /// <param name="certFile">Certificate File (used instead of the above Certificate Parameters)</param>
        /// <param name="certPassword">Certificate Password (used instead of the above Certificate Parameters)</param>
        /// <param name="attributes">A list of attributes to pass</param>
        /// <param name="signatureType">Whether to sign Response or Assertion</param>
        /// <returns>A base64Encoded string with a SAML response.</returns>
        public static string GetPostSamlResponse(string recipient, string issuer, string domain, string subject,
                                                 StoreLocation storeLocation, StoreName storeName, X509FindType findType, string certFile, string certPassword, object findValue,
                                                 Dictionary <string, string> attributes, SigningHelper.SignatureType signatureType)
        {
            ResponseType response = new ResponseType();

            // Response Main Area
            response.ID           = "_" + Guid.NewGuid().ToString();
            response.Destination  = recipient;
            response.Version      = "2.0";
            response.IssueInstant = System.DateTime.UtcNow;

            NameIDType issuerForResponse = new NameIDType();

            issuerForResponse.Value = issuer.Trim();

            response.Issuer = issuerForResponse;

            StatusType status = new StatusType();

            status.StatusCode       = new StatusCodeType();
            status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Success";

            response.Status = status;

            XmlSerializer responseSerializer =
                new XmlSerializer(response.GetType());

            StringWriter      stringWriter = new StringWriter();
            XmlWriterSettings settings     = new XmlWriterSettings();

            settings.OmitXmlDeclaration = true;
            settings.Indent             = true;
            settings.Encoding           = Encoding.UTF8;

            XmlWriter responseWriter = XmlTextWriter.Create(stringWriter, settings);

            string samlString = string.Empty;



            AssertionType assertionType = SamlHelper.CreateSamlAssertion(
                issuer.Trim(), recipient.Trim(), domain.Trim(), subject.Trim(), attributes);

            response.Items = new AssertionType[] { assertionType };

            responseSerializer.Serialize(responseWriter, response);
            responseWriter.Close();

            samlString = stringWriter.ToString();

            samlString = samlString.Replace("SubjectConfirmationData",
                                            string.Format("SubjectConfirmationData NotOnOrAfter=\"{0:o}\" Recipient=\"{1}\"",
                                                          DateTime.UtcNow.AddMinutes(5), recipient));

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);
            X509Certificate2 cert = null;

            if (System.IO.File.Exists(certFile))
            {
                cert = new X509Certificate2(certFile, certPassword);
            }
            else
            {
                X509Store store = new X509Store(storeName, storeLocation);
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection coll = store.Certificates.Find(findType, findValue, true);
                if (coll.Count < 1)
                {
                    throw new ArgumentException("Unable to locate certificate");
                }
                cert = coll[0];
                store.Close();
            }

            XmlElement signature =
                SigningHelper.SignDoc(doc, cert, "ID",
                                      (signatureType == SigningHelper.SignatureType.Response || signatureType == SigningHelper.SignatureType.TestVU475445) ? response.ID : assertionType.ID);

            doc.DocumentElement.InsertBefore(signature,
                                             doc.DocumentElement.ChildNodes[1]);

            if (SamlHelper.Logger.IsDebugEnabled)
            {
                SamlHelper.Logger.DebugFormat(
                    "Saml Assertion before encoding = {0}",
                    doc.OuterXml.ToString());
            }

            string responseStr = doc.OuterXml;

            // 2018Ma06 Special Post-signature Maniuplation postsignature to inject comment into subject.
            if (signatureType == SigningHelper.SignatureType.TestVU475445)
            {
                string sub        = subject.Trim();
                int    half       = sub.Length / 2;
                string firstHalf  = sub.Substring(0, half);
                string secondHalf = sub.Substring(half);
                responseStr = responseStr.Replace(sub, firstHalf + "<!--VU475445-->" + secondHalf);
                int breaker = 1;
            }


            byte[] base64EncodedBytes =
                Encoding.UTF8.GetBytes(responseStr);

            string returnValue = System.Convert.ToBase64String(
                base64EncodedBytes);

            return(returnValue);
        }
コード例 #24
0
        /// <summary>
        /// Creates a SAML 2.0 Assertion Segment for a Response
        /// Simple implmenetation assuming a list of string key and value pairs
        /// </summary>
        /// <param name="issuer"></param>
        /// <param name="assertionExpirationMinutes"></param>
        /// <param name="audience"></param>
        /// <param name="subject"></param>
        /// <param name="recipient"></param>
        /// <param name="attributes">Dictionary of string key, string value pairs</param>
        /// <returns>Assertion to sign and include in Response</returns>
        private static AssertionType CreateSaml20Assertion(string issuer,
                                                           int assertionExpirationMinutes,
                                                           string audience,
                                                           string subject,
                                                           string recipient,
                                                           Dictionary <string, string> attributes)
        {
            AssertionType newAssertion = new AssertionType
            {
                Version      = "2.0",
                IssueInstant = DateTime.UtcNow,
                ID           = "_" + Guid.NewGuid(),
                Issuer       = new NameIDType {
                    Value = issuer.Trim()
                }
            };

            // Create Issuer

            // Create Assertion Subject
            SubjectType subjectType           = new SubjectType();
            NameIDType  subjectNameIdentifier = new NameIDType {
                Value = subject.Trim(), Format = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
            };
            SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType {
                Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer", SubjectConfirmationData = new SubjectConfirmationDataType {
                    NotOnOrAfter = DateTime.UtcNow.AddMinutes(assertionExpirationMinutes), Recipient = recipient
                }
            };

            subjectType.Items    = new object[] { subjectNameIdentifier, subjectConfirmation };
            newAssertion.Subject = subjectType;

            // Create Assertion Conditions
            ConditionsType conditions = new ConditionsType
            {
                NotBefore             = DateTime.UtcNow,
                NotBeforeSpecified    = true,
                NotOnOrAfter          = DateTime.UtcNow.AddMinutes(assertionExpirationMinutes),
                NotOnOrAfterSpecified = true,
                Items = new ConditionAbstractType[] { new AudienceRestrictionType {
                                                          Audience = new[] { audience.Trim() }
                                                      } }
            };

            newAssertion.Conditions = conditions;

            // Add AuthnStatement and Attributes as Items
            AuthnStatementType authStatement = new AuthnStatementType {
                AuthnInstant = DateTime.UtcNow, SessionIndex = newAssertion.ID
            };
            AuthnContextType context = new AuthnContextType
            {
                ItemsElementName = new[] { ItemsChoiceType5.AuthnContextClassRef },
                Items            = new object[] { "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified" }
            };

            authStatement.AuthnContext = context;

            AttributeStatementType attributeStatement = new AttributeStatementType
            {
                Items = new object[attributes.Count]
            };
            int i = 0;

            foreach (KeyValuePair <string, string> attribute in attributes)
            {
                attributeStatement.Items[i] = new AttributeType
                {
                    Name           = attribute.Key,
                    AttributeValue = new object[] { attribute.Value },
                    NameFormat     = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
                };
                i++;
            }

            newAssertion.Items = new StatementAbstractType[] { authStatement, attributeStatement };

            return(newAssertion);
        }
コード例 #25
0
    private void CreateSAMLResponse()
    {
        FormsIdentity id = null;

        if (HttpContext.Current.User != null)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {
                    id = (FormsIdentity)HttpContext.Current.User.Identity;
                }
            }
        }

        DateTime notBefore    = (id != null ? id.Ticket.IssueDate.ToUniversalTime() : DateTime.UtcNow);
        DateTime notOnOrAfter = (id != null ? id.Ticket.Expiration.ToUniversalTime() : DateTime.UtcNow.AddMinutes(30));

        IDProvider config = IDProvider.GetConfig();

        SAMLResponse.Status                  = new StatusType();
        SAMLResponse.Status.StatusCode       = new StatusCodeType();
        SAMLResponse.Status.StatusCode.Value = SAMLUtility.StatusCodes.Success;

        AssertionType assert = new AssertionType();

        assert.ID           = SAMLUtility.GenerateID();
        assert.IssueInstant = DateTime.UtcNow.AddMinutes(10);

        assert.Issuer       = new NameIDType();
        assert.Issuer.Value = config.id;

        SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType();

        subjectConfirmation.Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer";
        subjectConfirmation.SubjectConfirmationData              = new SubjectConfirmationDataType();
        subjectConfirmation.SubjectConfirmationData.Recipient    = SAMLRequest.Issuer;
        subjectConfirmation.SubjectConfirmationData.InResponseTo = SAMLRequest.Request.ID;
        subjectConfirmation.SubjectConfirmationData.NotOnOrAfter = notOnOrAfter;

        NameIDType nameID = new NameIDType();

        nameID.Format = SAMLUtility.NameIdentifierFormats.Transient;
        nameID.Value  = (id != null ? id.Name : UtilBO.FormatNameFormsAuthentication(this.__SessionWEB.__UsuarioWEB.Usuario));

        assert.Subject       = new SubjectType();
        assert.Subject.Items = new object[] { subjectConfirmation, nameID };

        assert.Conditions                       = new ConditionsType();
        assert.Conditions.NotBefore             = notBefore;
        assert.Conditions.NotOnOrAfter          = notOnOrAfter;
        assert.Conditions.NotBeforeSpecified    = true;
        assert.Conditions.NotOnOrAfterSpecified = true;

        AudienceRestrictionType audienceRestriction = new AudienceRestrictionType();

        audienceRestriction.Audience = new string[] { SAMLRequest.Issuer };
        assert.Conditions.Items      = new ConditionAbstractType[] { audienceRestriction };

        AuthnStatementType authnStatement = new AuthnStatementType();

        authnStatement.AuthnInstant = DateTime.UtcNow;
        authnStatement.SessionIndex = SAMLUtility.GenerateID();

        authnStatement.AuthnContext       = new AuthnContextType();
        authnStatement.AuthnContext.Items =
            new object[] { "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" };

        authnStatement.AuthnContext.ItemsElementName =
            new ItemsChoiceType5[] { ItemsChoiceType5.AuthnContextClassRef };

        StatementAbstractType[] statementAbstract = new StatementAbstractType[] { authnStatement };
        assert.Items       = statementAbstract;
        SAMLResponse.Items = new object[] { assert };

        string xmlResponse = SAMLUtility.SerializeToXmlString(SAMLResponse);

        XmlDocument doc = new XmlDocument();

        doc.LoadXml(xmlResponse);
        XmlSignatureUtils.SignDocument(doc, assert.ID);
        SAMLResponse = SAMLUtility.DeserializeFromXmlString <ResponseType>(doc.InnerXml);

        HttpPostBinding binding = new HttpPostBinding(SAMLResponse, HttpUtility.UrlDecode(Request[HttpBindingConstants.RelayState]));

        binding.SendResponse(this.Context, HttpUtility.UrlDecode(SAMLRequest.AssertionConsumerServiceURL), SAMLTypeSSO.signon);
    }
コード例 #26
0
        private static void InterpretResponse(ResponseType response, EAuthResponseModel model)
        {
            model.RequestId = response.InResponseTo;

            // Пример за грешка:
            // <samlp:Status>
            //   <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:AuthnFailed" /></samlp:StatusCode>
            //   <samlp:StatusMessage>NOT_DETECTED_QES ***ИЛИ*** Некоректни данни</samlp:StatusMessage>
            // </samlp:Status>
            // Пример за успех:
            // <samlp:Status>
            //   <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
            //   <samlp:StatusMessage>Успешен отговор на заявката</samlp:StatusMessage>
            // </samlp:Status>
            StatusType status = response.Status;

            if (status != null)
            {
                bool isSuccessful = status.StatusCode?.Value.EndsWith("Success") ?? false;

                string statusMessage = status.StatusMessage;
                // Ако в заявката към еАвт не е подаден сертификат, системата вместо съобщение за грешка връща код NOT_DETECTED_QES
                // ИЛИ съобщение "STS Exception: STSToken exception: bg.egov.mtits.eauthn.delegate.exceptions.STSDelegateException : null".
                if (statusMessage == "NOT_DETECTED_QES" || statusMessage != null && statusMessage.Contains("STSDelegateException"))
                {
                    model.NotDetectedQes = true;
                    model.Errors.Add(ClientCertNotSelected);
                }
                else if (!isSuccessful)  // Съобщението за успех не се пази.
                {
                    if (!string.IsNullOrEmpty(statusMessage))
                    {
                        model.Errors.Add(statusMessage);
                    }

                    XmlElement[] details = status.StatusDetail?.Any;
                    if (details != null)
                    {
                        model.Errors.AddRange(details.Select(e => e.OuterXml));
                    }
                }
            }

            if (response.Items?[0] is AssertionType assertion)
            {
                ConditionsType conditions = assertion.Conditions;
                if (conditions != null && conditions.NotOnOrAfterSpecified)
                {
                    model.ExpirationDateTime = conditions.NotOnOrAfter;
                }

                // Пример за ЕГН:
                // <saml2:Subject>
                //   <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" NameQualifier="urn:egov:bg:eauth:1.0:attributes:eIdentifier:EGN">8012311234</saml2:NameID>
                //   <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:sender-vouches"><saml2:SubjectConfirmationData /></saml2:SubjectConfirmation>
                // </saml2:Subject>
                NameIDType nameId = assertion.Subject?.Items?.OfType <NameIDType>().FirstOrDefault();
                if (nameId != null)
                {
                    model.PidTypeCode      = nameId.NameQualifier?.Split(':').Last(); // Към 2018-02 е известен само вид "EGN".
                    model.PersonIdentifier = nameId.Value;
                }

                // Пример за име и контакти:
                // <saml2:AttributeStatement>
                //   <saml2:Attribute Name="urn:egov:bg:eauth:1.0:attributes:personNamesLatin" NameFormat="urn:egov:bg:eauth:1.0:attributes:personNamesLatin">
                //     <saml2:AttributeValue xsi:type="xs:string">Ivan Dilyanov Dilov</saml2:AttributeValue>
                //   </saml2:Attribute>
                //   <saml2:Attribute Name="urn:egov:bg:eauth:1.0:attributes:eMail" NameFormat="urn:egov:bg:eauth:1.0:attributes:eMail">
                //     <saml2:AttributeValue xsi:type="xs:string">[email protected]</saml2:AttributeValue>
                //   </saml2:Attribute>
                //   <saml2:Attribute Name="urn:egov:bg:eauth:1.0:attributes:phone" NameFormat="urn:egov:bg:eauth:1.0:attributes:phone">
                //     <saml2:AttributeValue xsi:type="xs:string">+359 888476663</saml2:AttributeValue>
                //   </saml2:Attribute>
                // </saml2:AttributeStatement>
                if (assertion.Items != null)
                {
                    foreach (AttributeStatementType attributes in assertion.Items.OfType <AttributeStatementType>())
                    {
                        if (attributes.Items != null)
                        {
                            foreach (AttributeType attribute in attributes.Items.OfType <AttributeType>())
                            {
                                string type  = attribute.Name?.Split(':').Last().ToLower();
                                string value = attribute.AttributeValue != null?string.Join(Environment.NewLine, attribute.AttributeValue.Where(v => v != null)) : null;

                                if (type == "personnameslatin")
                                {
                                    model.PersonNamesLatin = value;
                                }
                                else if (type == "email")
                                {
                                    model.Email = value;
                                }
                                else if (type == "phone")
                                {
                                    model.Phone = value;
                                }
                            }
                        }
                    }
                }
            }
        }