private static XmlDocument SignSamlRequest(AuthnRequestType request, string signatureNsPrefix, bool includePublicKey, string sslCertificateThumbprint)
        {
            X509Certificate2 cert = SignUtil.LoadCertificate(StoreName.My, StoreLocation.LocalMachine, sslCertificateThumbprint);

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("samlp", _samlProtocolNs);
            if (!string.IsNullOrEmpty(signatureNsPrefix))
            {
                ns.Add(signatureNsPrefix, SignUtil.SignatureNamespace);
            }
            ns.Add("egovbga", _eauthExtNs);
            ns.Add("saml", _samlAssertionNs);
            XmlDocument doc = request.ToXmlDocument(ns);

            XmlElement signatureElement = SignUtil.Sign(doc, cert, signatureNsPrefix, includePublicKey);

            // Подписът вече е добавен в XML документа и по подразбиране е в края му. Според "saml-schema-protocol-2.0.xsd" обаче,
            // подписът трябва да бъде между елементите Issuer и Extensions. InsertAfter() го маха от старото място и го закача на новото.
            XmlNode issuerElement = doc.GetElementsByTagName(nameof(request.Issuer), _samlAssertionNs)[0];

            doc.DocumentElement.InsertAfter(signatureElement, issuerElement);

            return(doc);
        }
Exemplo n.º 2
0
        public static AuthnRequestType GetSamlAuthnRequest(HttpContext context, ServiceProviderModel serviceProvider)
        {
            var authnRequest = new AuthnRequestType()
            {
                ID                          = AuthnRequestID = Guid.NewGuid().ToString(),
                Version                     = "2.0",
                IssueInstant                = DateTime.UtcNow,
                ProtocolBinding             = Saml2Constants.ProtocolBindings.HTTP_Post,
                AssertionConsumerServiceURL = serviceProvider.AssertionConsumerServiceUrl //$"{ context.Request.Scheme}://{context.Request.Host}{context.Request.PathBase}",
            };

            authnRequest.Issuer = new NameIDType {
                Value = serviceProvider.Name
            };
            authnRequest.NameIDPolicy = new NameIDPolicyType {
                Format = Saml2Constants.NameIdentifierFormats.Unspecified, AllowCreate = true
            };
            authnRequest.RequestedAuthnContext = new RequestedAuthnContextType
            {
                Comparison       = AuthnContextComparisonType.exact,
                Items            = new string[] { "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" },
                ItemsElementName = new[] { ItemsChoiceType7.AuthnContextClassRef }
            };

            return(authnRequest);
        }
        public Guid?GetSessionID(string userID, string vendor, string ipAddress)
        {
            AuthnRequestType auth = SSOTools.CreateAuthnRequest(userID, vendor, ipAddress);

            auth.Signature = SSOTools.Sign(auth, auth.ID, _clientCertificate);

            ChannelFactory <ISSOService> channelFactory = new ChannelFactory <ISSOService>("BasicHttpBinding_ISSOService");
            ISSOService  ssoClient = channelFactory.CreateChannel();
            ResponseType r         = ssoClient.GetSSO(new GetSSORequest {
                AuthnRequest = auth
            }).Response;

            channelFactory.Close();

            if (SSOTools.VerifySignature(r, _serverCertificate))
            {
                Dictionary <string, string> attributes = SSOTools.GetAttributes(r);
                Guid cleverDomeSessionGuid             = new Guid(attributes["SessionID"]);
                //int timeOut = int.Parse(attributes["SessionTimeOut"]); // Time Out of the session.
                return(cleverDomeSessionGuid);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Checks if the client request is valid and shows the login form
        /// </summary>
        /// <param name="samlRequest">SAML request by the client</param>
        //GET /SAML/AuthnRequest?SAMLRequest=base64encodedSAMLAuthnRequest
        public ActionResult AuthnRequest(string samlRequest)
        {
            if (samlRequest != null)
            {
                //Extract SAMLRequest
                XmlSerializer serializer = new XmlSerializer(typeof(AuthnRequestType));

                string samlRequestXML =
                    System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(samlRequest));

                AuthnRequestType authnRequest =
                    (AuthnRequestType)serializer.Deserialize(new StringReader(samlRequestXML));

                if (trusted.ContainsKey(authnRequest.Issuer.Value))
                {
                    ViewBag.requester = authnRequest.Issuer.Value;

                    //user enters credentials
                    return(View("Login"));
                }
                else
                {
                    //Source of request not trusted
                    return(View("NotTrusted"));
                }
            }

            return(View());
        }
Exemplo n.º 5
0
        /// <summary>
        /// Creates a SAMLRequest object and serializes it.
        /// </summary>
        /// <returns>The serialized SAMLRequest object</returns>
        private string CreateSAMLRequest()
        {
            AuthnRequestType samlRequest = new AuthnRequestType()
            {
                ID           = Guid.NewGuid().ToString(),
                Version      = "2.0",
                IssueInstant = DateTime.UtcNow,
                Issuer       = new NameIDType
                {
                    Value = clientBaseAddress
                },
                NameIDPolicy = new NameIDPolicyType
                {
                    AllowCreate = true,
                    Format      = "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
                }
            };

            XmlSerializer serializer = new XmlSerializer(typeof(AuthnRequestType));
            StringWriter  writer     = new StringWriter();

            serializer.Serialize(writer, samlRequest);

            string base64EncodedRequest = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(writer.ToString()));

            return(base64EncodedRequest);
        }
        protected virtual async Task <ResponseType> BuildResponse(AuthnRequestType authnRequest, RelyingPartyAggregate relyingParty, NameIDPolicyValidationResult validationResult, CancellationToken cancellationToken)
        {
            var builder = SamlResponseBuilder.New()
                          .AddAssertion(cb =>
            {
                cb.SetIssuer(Constants.NameIdentifierFormats.PersistentIdentifier, _options.IDPId);
                cb.SetSubject(s =>
                {
                    s.SetNameId(validationResult.NameIdFormat, validationResult.NameIdValue);
                    s.AddSubjectConfirmationBearer(DateTime.UtcNow, DateTime.UtcNow.AddSeconds(relyingParty.AssertionExpirationTimeInSeconds), inResponseTo: authnRequest.ID);
                });
                cb.SetConditions(DateTime.UtcNow, DateTime.UtcNow.AddSeconds(relyingParty.AssertionExpirationTimeInSeconds), c =>
                {
                    c.AddAudienceRestriction(relyingParty.Id);
                });
                foreach (var attr in validationResult.Attributes)
                {
                    cb.AddAttributeStatementAttribute(attr.AttributeName, null, attr.Type, attr.Value);
                }
            });

            if (await relyingParty.GetAssertionSigned(_entityDescriptorStore, cancellationToken))
            {
                return(builder.SignAndBuild(_options.SigningCertificate, _options.SignatureAlg.Value, _options.CanonicalizationMethod));
            }

            return(builder.Build());
        }
Exemplo n.º 7
0
        public string RedirectableAuthRequest(SamlRequestOption requestOption, string xmlPrivateKey = "")
        {
            try
            {
                _logger.LogInformation("RedirectableAuthRequest -> initialize request for IDP {0}", requestOption.Destination);
                AuthnRequestType authnRequest = _authRequestTypeMapper.Map(requestOption);
                authnRequest.ProtocolBinding = SamlNamespaceHelper.SAML_PROTOCOL_BINDING_REDIRECT_NAMESPACE;
                _logger.LogInformation("RedirectableAuthRequest -> request created with id {0}", authnRequest.ID);

                string compressedRequest = WebUtility.UrlEncode(CompressRequest(authnRequest));
                string sigAlg            = WebUtility.UrlEncode(SignatureHelper.SIGNATURE_ALGORITHM_SHA256);

                _logger.LogInformation("RedirectableAuthRequest -> generating signature for id {0}...", authnRequest.ID);
                string tmpRequest       = string.Concat("SAMLRequest=", compressedRequest, "&SigAlg=", sigAlg);
                string requestSignature = _signatureHelper.SignMessage(tmpRequest, requestOption.Certificate, xmlPrivateKey);
                _logger.LogInformation("RedirectableAuthRequest -> signature generated correctly");

                string requestQueryString = string.Concat(tmpRequest, "&Signature=", requestSignature);
                _logger.LogDebug("RedirectableAuthRequest -> request id {0} - query string: {1}", authnRequest.ID, requestQueryString);
                _traceLogger.LogInformation("AuthnReq_ID: {0}|AuthnReq_IssueInstant: {1}|AuthnReq_QS: {2}", authnRequest.ID, authnRequest.IssueInstant, requestQueryString);
                return(requestQueryString);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "RedirectableAuthRequest -> error on creating redirectable auth request");
                throw;
            }
        }
        protected virtual async Task <RelyingPartyAggregate> CheckRelyingParty(AuthnRequestType authnRequest, CancellationToken cancellationToken)
        {
            var relyingParty = await _relyingPartyRepository.Get(authnRequest.Issuer.Value, cancellationToken);

            if (relyingParty == null)
            {
                throw new SamlException(HttpStatusCode.NotFound, Saml.Constants.StatusCodes.Requester, string.Format(Global.UnknownIssuer, nameof(authnRequest.Issuer.Value)));
            }

            if (await relyingParty.GetAuthnRequestsSigned(_entityDescriptorStore, cancellationToken))
            {
                var certificates = await relyingParty.GetSigningCertificates(_entityDescriptorStore, cancellationToken);

                foreach (var certificate in certificates)
                {
                    if (SignatureHelper.CheckSignature(authnRequest.SerializeToXmlElement(), certificate))
                    {
                        return(relyingParty);
                    }
                }

                throw new SamlException(HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.Requester, Global.BadAuthnRequestSignature);
            }

            if ((await relyingParty.GetAssertionLocation(_entityDescriptorStore, Saml.Constants.Bindings.HttpRedirect, cancellationToken)) == null)
            {
                throw new SamlException(HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.UnsupportedBinding, Global.BadSPAssertionLocation);
            }

            return(relyingParty);
        }
        protected virtual IAuthenticator CheckAuthnContextClassRef(AuthnRequestType authnRequest)
        {
            if (authnRequest.RequestedAuthnContext != null)
            {
                AuthnContextComparisonType comparison = AuthnContextComparisonType.exact;
                // TODO : Support other comparison.
                if (authnRequest.RequestedAuthnContext.ComparisonSpecified)
                {
                    comparison = authnRequest.RequestedAuthnContext.Comparison;
                }

                if (authnRequest.RequestedAuthnContext.Items == null || !authnRequest.RequestedAuthnContext.Items.Any())
                {
                    throw new SamlException(HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.NoAuthnContext, Global.MissingAuthnContextClassRef);
                }

                var items = authnRequest.RequestedAuthnContext.Items;
                switch (comparison)
                {
                case AuthnContextComparisonType.exact:
                    var auth = _authenticators.FirstOrDefault(a => items.Contains(a.AuthnContextClassRef));
                    if (auth == null)
                    {
                        throw new SamlException(HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.NoAuthnContext, string.Format(Global.UnknownAuthContextClassRef, string.Join(",", items)));
                    }

                    return(auth);
                }
            }

            return(_authenticators.First(a => a.AuthnContextClassRef == _options.DefaultAuthnContextClassRef));
        }
Exemplo n.º 10
0
        public static ResponseType CreateErrorSamlResponse(AuthnRequestType samlAuthRequest)
        {
            var samlResponse = new ResponseType(true)
            {
                ID           = "_" + Guid.NewGuid(),
                Version      = "2.0",
                IssueInstant = System.DateTime.UtcNow,
                Destination  = samlAuthRequest.AssertionConsumerServiceURL,
                InResponseTo = samlAuthRequest.ID,
                Issuer       = new NameIDType()
                {
                    Value = ISSUER
                },
                Status = new StatusType()
                {
                    StatusCode = new StatusCodeType()
                    {
                        Value = Saml2Constants.StatusCodes.AuthnFailed
                    }
                }
            };

            samlResponse.Items = new AssertionType[] { };

            return(samlResponse);
        }
Exemplo n.º 11
0
        public static ResponseType CreateSuccessSamlResponse(AuthnRequestType samlAuthRequest)
        {
            var samlResponse = new ResponseType(true)
            {
                ID           = "_" + Guid.NewGuid(),
                Version      = "2.0",
                IssueInstant = System.DateTime.UtcNow,
                Destination  = samlAuthRequest.AssertionConsumerServiceURL,
                InResponseTo = samlAuthRequest.ID,
                Issuer       = new NameIDType()
                {
                    Value = ISSUER
                },
                Status = new StatusType()
                {
                    StatusCode = new StatusCodeType()
                    {
                        Value = Saml2Constants.StatusCodes.Success
                    }
                }
            };

            samlResponse.Items = new AssertionType[] { CreateSamlAssertion(samlAuthRequest, _context.User.FindFirst("Username").Value) };

            return(samlResponse);
        }
Exemplo n.º 12
0
        public static XmlDocument toXmlDocument(AuthnRequestType authnRequest)
        {
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

            ns.Add("samlp", Saml2Constants.SAML2_PROTOCOL_NAMESPACE);
            ns.Add("saml", Saml2Constants.SAML2_ASSERTION_NAMESPACE);

            XmlRootAttribute xRoot = new XmlRootAttribute();

            xRoot.ElementName = "AuthnRequest";
            xRoot.Namespace   = Saml2Constants.SAML2_PROTOCOL_NAMESPACE;
            XmlSerializer serializer    = new XmlSerializer(typeof(AuthnRequestType), xRoot);
            MemoryStream  memoryStream  = new MemoryStream();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

            serializer.Serialize(xmlTextWriter, authnRequest, ns);

            XmlDocument document = new XmlDocument();

            memoryStream.Seek(0, SeekOrigin.Begin);
            document.Load(memoryStream);
            xmlTextWriter.Close();

            return(document);
        }
Exemplo n.º 13
0
        public string PostableAuthRequest(SamlRequestOption requestOption, string xmlPrivateKey = "")
        {
            try
            {
                _logger.LogInformation("PostableAuthRequest -> initialize request for IDP {0}", requestOption.Destination);
                _logger.LogInformation("PostableAuthRequest -> creating request for authentication...");
                AuthnRequestType authnRequest = _authRequestTypeMapper.Map(requestOption);
                _logger.LogInformation("PostableAuthRequest -> request created with id {0}", authnRequest.ID);

                XmlDocument xmlRequest = new XmlDocument();
                xmlRequest.LoadXml(authnRequest.ToXmlString());

                _logger.LogInformation("PostableAuthRequest -> generating signature for id {0}...", authnRequest.ID);
                XmlElement signatureElement = _signatureHelper.GetXmlAuthRequestSignature(xmlRequest, requestOption.Certificate, xmlPrivateKey);
                xmlRequest.DocumentElement.InsertAfter(signatureElement, xmlRequest.DocumentElement.ChildNodes[0]);
                _logger.LogInformation("PostableAuthRequest -> signature generated correctly");

                _logger.LogDebug("PostableAuthRequest -> request id: {0} xml: {1}", authnRequest.ID, xmlRequest.OuterXml);
                _traceLogger.LogInformation("AuthnReq_ID: {0}|AuthnReq_IssueInstant: {1}|AuthnReq_SAML: {2}", authnRequest.ID, authnRequest.IssueInstant, xmlRequest.OuterXml);
                return(Convert.ToBase64String(Encoding.UTF8.GetBytes(xmlRequest.OuterXml)));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "PostableAuthRequest -> error on creating postable auth request");
                throw;
            }
        }
 private AuthnRequestBuilder(string providerName)
 {
     _authRequest = new AuthnRequestType
     {
         ID           = $"pfx{Guid.NewGuid().ToString()}",
         Version      = Constants.SamlVersion,
         IssueInstant = DateTime.UtcNow,
         ProviderName = providerName
     };
 }
        public static XmlDocument CreateSamlRequest(
            string eAuthUrl,
            string callerOid,
            string callerName,
            string idPrefix,  // Не трябва да започва с цифра.
            string requestUrl,
            string callbackUrl,
            string requestedServiceOid,
            string requestedProviderOid,
            // Параметри за подписването.
            string signatureNsPrefix,
            bool includePublicKey,
            string sslCertificateThumbprint,
            out string id)
        {
            DateTime now = DateTime.Now;

            // Закръгление до милисекунди.
            now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond);
            id  = $"{idPrefix ?? "ID"}_{now.ToString(_requestIdDateTimeFormat, System.Globalization.CultureInfo.InvariantCulture)}";

            AuthnRequestType authnRequest = new AuthnRequestType
            {
                ID      = id,
                Version = "2.0",
                // Според дадения пример, IssueInstant="2015-06-29T03:00:09", т.е. стойността е закръглена до секунда и няма time zone.
                IssueInstant                = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, DateTimeKind.Unspecified),
                ProtocolBinding             = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
                Destination                 = eAuthUrl,
                ForceAuthn                  = true,
                ForceAuthnSpecified         = true,
                IsPassive                   = false,
                IsPassiveSpecified          = true,
                ProviderName                = callerName,
                AssertionConsumerServiceURL = callbackUrl,
                // Информационна система, която инициира автентификация.
                Issuer = new NameIDType
                {
                    SPProvidedID = callerOid,
                    Value        = requestUrl
                },
                // Според документацията: версия на услугата + информационна система, която я предоставя.
                // Реално работи също и с информационна система + администрация-собственик.
                Extensions = new ExtensionsType
                {
                    RequestedService = new RequestedServiceType
                    {
                        Service  = requestedServiceOid,
                        Provider = requestedProviderOid
                    }
                }
            };

            return(SignSamlRequest(authnRequest, signatureNsPrefix, includePublicKey, sslCertificateThumbprint));
        }
Exemplo n.º 16
0
        public XmlDocument EndpointMapSamlRequest(Endpoint endpoint)
        {
            AuthnRequestType request = new AuthnRequestType
            {
                ID           = Helper.GuidAsIdString(endpoint.Id),
                Version      = Saml.Names.SAMLVersion,
                ProviderName = endpoint.Description,
                Destination  = endpoint.Login,
                IssueInstant = DateTime.UtcNow,
                Issuer       = new NameIDType {
                    Value = endpoint.Requestor
                },
                AssertionConsumerServiceURL = endpoint.Requestor,
                ProtocolBinding             = Saml.Names.SAMLNamesProtocolBindingPOST,
                ForceAuthn = false, ForceAuthnSpecified = true, //When ForceAuthn true, user will be forced to re-authenticate, even if valid session
                IsPassive  = false, IsPassiveSpecified = true,  //When IsPassive true, authenticate user silently, without user interaction, using the session cookie if one exists
                Subject    = new SubjectType
                {
                    Items = new object[] {
                        new NameIDType {
                            Value = endpoint.Id, Format = Saml.Names.SAMLNamesFormatIssuerEntity
                        },
                        new SubjectConfirmationType
                        {
                            Method = Saml.Names.SAMLNamesSubjectConfirmationBaerer,
                            SubjectConfirmationData = new SubjectConfirmationDataType
                            {
                                NotOnOrAfter = DateTime.UtcNow.AddMinutes(Saml.Names.SAMLAssertionExpirationMinutes),
                                Recipient    = endpoint.Requestor
                            }
                        }
                    }
                },
                Conditions = new ConditionsType
                {
                    NotBefore    = DateTime.UtcNow, NotBeforeSpecified = true,
                    NotOnOrAfter = DateTime.UtcNow.AddMinutes(Saml.Names.SAMLAssertionExpirationMinutes), NotOnOrAfterSpecified = true,
                    Items        = new ConditionAbstractType[] { new AudienceRestrictionType {
                                                                     Audience = new string[] { endpoint.Referrer }
                                                                 } }
                }
            };

            XmlDocument xmlRequest = Saml.Helper.SerializeAndSignSAMLType <AuthnRequestType>(request, request.ID);

            return(xmlRequest);
        }
Exemplo n.º 17
0
        private AuthnRequestType AuthnRequestTypeCreate()
        {
            AuthnRequestType _request = new AuthnRequestType();

            _request.ID                          = "_" + Guid.NewGuid().ToString();
            _request.Version                     = "2.0";
            _request.IssueInstant                = DateTime.UtcNow;
            _request.Destination                 = ama_Destination;
            _request.Consent                     = "urn:oasis:names:tc:SAML:2.0:consent:unspecified";
            _request.ProtocolBinding             = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
            _request.AssertionConsumerServiceURL = ama_AssertionConsumerServiceURL;
            _request.ProviderName                = ama_ProviderName;
            _request.Issuer                      = new NameIDType();
            _request.Issuer.Value                = "http://localhost:64181";
            _request.Extensions                  = new ExtensionsType();

            _request.Extensions.Any = new XmlElement[] { RequestAttributeCreate() };
            return(_request);
        }
        public string GetNewTransaction(AuthenticationRequest authenticationRequest)
        {
            if (authenticationRequest == null)
            {
                throw new ArgumentNullException("authenticationRequest");
            }

            var authnRequest = new AuthnRequestType
            {
                ID                                      = authenticationRequest.MerchantReference,
                Version                                 = Constants.BankIdAuthnRequestTypeVersion,
                IssueInstant                            = authenticationRequest.CreateDateTimestamp,
                ForceAuthn                              = true,
                IsPassive                               = false,
                ProtocolBinding                         = Constants.BankIdProtocolBinding,
                AssertionConsumerServiceURL             = _configuration.MerchantReturnUrl.AbsoluteUri,
                AttributeConsumingServiceIndex          = (ushort)authenticationRequest.RequestedServiceId,
                AttributeConsumingServiceIndexSpecified = true,
                Issuer                                  = new NameIDType
                {
                    Value = _configuration.MerchantId
                },
                Conditions            = new ConditionsType(),
                RequestedAuthnContext = new RequestedAuthnContextType
                {
                    Comparison          = AuthnContextComparisonType.minimum,
                    ComparisonSpecified = true,
                    ItemsElementName    = new[] { ItemsChoiceType7.AuthnContextClassRef },
                    Items = new[] { GetLevelOfAssuranceString(authenticationRequest.AssuranceLevel) }
                },
                Extensions = GetAuthnRequestExtensions(authenticationRequest),
                Scoping    = new ScopingType()
            };

            return(DateTimeHelper.ProcessDateTimes(authnRequest.Serialize(), _dateTimeElementNames));
        }
Exemplo n.º 19
0
 private void ValidateSamlRequest(AuthnRequestType samlAuthRequest)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 20
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);
        }
Exemplo n.º 21
0
        /// <summary>
        /// Validates the authn response.
        /// </summary>
        /// <param name="response">The response.</param>
        /// <param name="request">The request.</param>
        /// <param name="metadataIdp">The metadata idp.</param>
        /// <exception cref="Exception">
        /// </exception>
        public static void ValidateAuthnResponse(this ResponseType response, AuthnRequestType request, EntityDescriptor metadataIdp)
        {
            // Verify signature
            var xmlDoc = response.SerializeToXmlDoc();

            BusinessValidation.ValidationCondition(() => response.Status == null, ErrorLocalization.StatusNotValid);
            BusinessValidation.ValidationCondition(() => response.Status.StatusCode == null, ErrorLocalization.StatusCodeNotValid);

            if (!response.Status.StatusCode.Value.Equals(SamlConst.Success, StringComparison.InvariantCultureIgnoreCase))
            {
                if (int.TryParse(response.Status.StatusMessage?.Replace("ErrorCode nr", ""), out var errorCode))
                {
                    switch (errorCode)
                    {
                    case 19:
                        throw new Exception(ErrorLocalization._19);

                    case 20:
                        throw new Exception(ErrorLocalization._20);

                    case 21:
                        throw new Exception(ErrorLocalization._21);

                    case 22:
                        throw new Exception(ErrorLocalization._22);

                    case 23:
                        throw new Exception(ErrorLocalization._23);

                    case 25:
                        throw new Exception(ErrorLocalization._25);

                    default:
                        break;
                    }
                }
                throw new Exception(ErrorLocalization.StatusCodeNotValid);
            }

            BusinessValidation.ValidationCondition(() => response.Signature == null, ErrorLocalization.ResponseSignatureNotFound);
            BusinessValidation.ValidationCondition(() => response?.GetAssertion() == null, ErrorLocalization.ResponseAssertionNotFound);
            BusinessValidation.ValidationCondition(() => response.GetAssertion()?.Signature == null, ErrorLocalization.AssertionSignatureNotFound);
            BusinessValidation.ValidationCondition(() => response.GetAssertion().Signature.KeyInfo.GetX509Data().GetX509Certificate() != response.Signature.KeyInfo.GetX509Data().GetX509Certificate(), ErrorLocalization.AssertionSignatureDifferent);
            var metadataXmlDoc = metadataIdp.SerializeToXmlDoc();

            BusinessValidation.ValidationCondition(() => XmlHelpers.VerifySignature(xmlDoc, metadataXmlDoc), ErrorLocalization.InvalidSignature);

            var respSigningCert = X509Helpers.AddCertificateHeaders(response.Signature.KeyInfo.GetX509Data().GetX509Certificate());

            using var responseCertificate = new X509Certificate2(Encoding.UTF8.GetBytes(respSigningCert));
            var assertSigningCert = X509Helpers.AddCertificateHeaders(response.GetAssertion()?.Signature.KeyInfo.GetX509Data().GetX509Certificate());

            using var assertionCertificate = new X509Certificate2(Encoding.UTF8.GetBytes(assertSigningCert));
            var idpSigningCert = X509Helpers.AddCertificateHeaders(metadataIdp.IDPSSODescriptor.KeyDescriptor.KeyInfo.X509Data.X509Certificate);

            using var idpCertificate = new X509Certificate2(Encoding.UTF8.GetBytes(idpSigningCert));

            BusinessValidation.ValidationCondition(() => responseCertificate.Thumbprint != idpCertificate.Thumbprint, ErrorLocalization.ResponseSignatureNotValid);
            BusinessValidation.ValidationCondition(() => assertionCertificate.Thumbprint != idpCertificate.Thumbprint, ErrorLocalization.AssertionSignatureNotValid);

            BusinessValidation.ValidationCondition(() => response.Version != SamlConst.Version, ErrorLocalization.VersionNotValid);
            BusinessValidation.ValidationNotNullNotWhitespace(response.ID, nameof(response.ID));

            BusinessValidation.ValidationNotNull(response.GetAssertion()?.GetAttributeStatement(), ErrorFields.Assertion);
            BusinessValidation.ValidationCondition(() => response.GetAssertion().GetAttributeStatement()?.GetAttributes()?.Count() == 0, ErrorLocalization.AttributeNotFound);
            BusinessValidation.ValidationCondition(() => response.GetAssertion().GetAttributeStatement()?.GetAttributes()?.Any(a => a.AttributeValue == null) ?? false, ErrorLocalization.AttributeNotFound);

            var listAttribute = new List <string>
            {
                SamlConst.fiscalNumber,
                SamlConst.digitalAddress,
                SamlConst.name,
                SamlConst.familyName,
                SamlConst.email,
                SamlConst.address,
                SamlConst.companyName,
                SamlConst.countyOfBirth,
                SamlConst.dateOfBirth,
                SamlConst.expirationDate,
                SamlConst.fiscalNumber,
                SamlConst.gender,
                SamlConst.idCard,
                SamlConst.ivaCode,
                SamlConst.mobilePhone,
                SamlConst.placeOfBirth,
                SamlConst.registeredOffice,
                SamlConst.spidCode,
            };

            var           attribute      = response.GetAssertion().GetAttributeStatement().GetAttributes();
            List <string> attributeNames = new List <string>();

            attributeNames.AddRange(attribute.Where(x => !string.IsNullOrWhiteSpace(x.Name) && !x.Name.StartsWith("urn")).Select(x => x.Name).ToList());
            BusinessValidation.ValidationCondition(() => attributeNames.Count() == 0, ErrorLocalization.AttributeRequiredNotFound);
            if (attributeNames.Count() > 0)
            {
                BusinessValidation.ValidationCondition(() => attributeNames.Any(x => !listAttribute.Contains(x)), ErrorLocalization.AttributeRequiredNotFound);
            }
            else
            {
                listAttribute.Add(SamlConst.firstname);
                listAttribute.Add(SamlConst.surname);
                listAttribute.Add(SamlConst.mail);
                attributeNames.AddRange(attribute.Where(x => !string.IsNullOrWhiteSpace(x.FriendlyName)).Select(x => x.FriendlyName).ToList());
                BusinessValidation.ValidationCondition(() => attributeNames.Count() == 0, ErrorLocalization.AttributeRequiredNotFound);
                if (attributeNames.Count() > 0)
                {
                    BusinessValidation.ValidationCondition(() => listAttribute.All(x => !attributeNames.Contains(x)), ErrorLocalization.AttributeRequiredNotFound);
                }
            }

            BusinessValidation.ValidationCondition(() => response.IssueInstant == default, ErrorLocalization.IssueInstantMissing);
            DateTimeOffset issueIstant        = new DateTimeOffset(response.IssueInstant);
            var            issueIstantRequest = DateTimeOffset.Parse(request.IssueInstant);

            BusinessValidation.ValidationCondition(() => (issueIstant - issueIstantRequest).Duration() > TimeSpan.FromMinutes(10), ErrorLocalization.IssueIstantDifferentFromRequest);

            BusinessValidation.ValidationNotNullNotWhitespace(response.InResponseTo, nameof(response.InResponseTo));

            BusinessValidation.ValidationNotNullNotWhitespace(response.Destination, nameof(response.Destination));

            if (!string.IsNullOrWhiteSpace(request.AssertionConsumerServiceURL))
            {
                BusinessValidation.ValidationCondition(() => !response.Destination.Equals(request.AssertionConsumerServiceURL), string.Format(ErrorLocalization.DifferentFrom, nameof(response.Destination), nameof(request.AssertionConsumerServiceURL)));
            }

            BusinessValidation.ValidationNotNullNotEmpty(response.Status, nameof(response.Status));

            BusinessValidation.ValidationCondition(() => response.Issuer == null, ErrorLocalization.IssuerNotSpecified);
            BusinessValidation.ValidationCondition(() => string.IsNullOrWhiteSpace(response.Issuer?.Value), ErrorLocalization.IssuerMissing);
            BusinessValidation.ValidationCondition(() => !response.Issuer.Value.Equals(metadataIdp.EntityID, StringComparison.InvariantCultureIgnoreCase), ErrorLocalization.IssuerDifferentFromEntityId);

            BusinessValidation.ValidationCondition(() => !string.IsNullOrWhiteSpace(response.Issuer.Format) && !response.Issuer.Format.Equals(SamlConst.IssuerFormat), ErrorLocalization.IssuerFormatDifferent);

            BusinessValidation.ValidationNotNullNotEmpty(response?.GetAssertion(), ErrorFields.Assertion);
            BusinessValidation.ValidationCondition(() => response.GetAssertion().ID == null, string.Format(ErrorLocalization.Missing, ErrorFields.ID));
            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().ID, ErrorFields.ID);
            BusinessValidation.ValidationCondition(() => response.GetAssertion().Version != SamlConst.Version, string.Format(ErrorLocalization.DifferentFrom, ErrorFields.Version, SamlConst.Version));

            BusinessValidation.ValidationCondition(() => response.GetAssertion().IssueInstant == null, string.Format(ErrorLocalization.NotSpecified, ErrorFields.IssueInstant));
            DateTimeOffset assertionIssueIstant = response.GetAssertion().IssueInstant;

            BusinessValidation.ValidationCondition(() => assertionIssueIstant > issueIstantRequest.AddMinutes(10), ErrorLocalization.IssueIstantAssertionGreaterThanRequest);
            BusinessValidation.ValidationCondition(() => assertionIssueIstant < issueIstantRequest, ErrorLocalization.IssueIstantAssertionLessThanRequest);

            BusinessValidation.ValidationCondition(() => (assertionIssueIstant - issueIstantRequest).Duration() > TimeSpan.FromMinutes(10), assertionIssueIstant > issueIstantRequest ? ErrorLocalization.IssueIstantAssertionGreaterThanRequest : ErrorLocalization.IssueIstantAssertionLessThanRequest);

            BusinessValidation.ValidationNotNull(response.GetAssertion().Subject, ErrorFields.Subject);
            BusinessValidation.ValidationNotNull(response.GetAssertion().Subject?.Items, ErrorFields.Subject);
            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().Subject?.GetNameID()?.Value, ErrorFields.NameID);
            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().Subject?.GetNameID()?.Format, ErrorFields.Format);
            BusinessValidation.ValidationCondition(() => !response.GetAssertion().Subject.GetNameID().Format.Equals(request.NameIDPolicy.Format), string.Format(ErrorLocalization.ParameterNotValid, ErrorFields.Format));
            BusinessValidation.ValidationCondition(() => response.GetAssertion().Subject.GetNameID().NameQualifier == null, string.Format(ErrorLocalization.NotSpecified, "Assertion.NameID.NameQualifier"));
            BusinessValidation.ValidationCondition(() => String.IsNullOrWhiteSpace(response.GetAssertion().Subject.GetNameID().NameQualifier), string.Format(ErrorLocalization.Missing, "Assertion.NameID.NameQualifier"));
            BusinessValidation.ValidationNotNullNotEmpty(response.GetAssertion().Subject.GetSubjectConfirmation(), ErrorFields.SubjectConfirmation);
            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().Subject.GetSubjectConfirmation().Method, ErrorFields.Method);
            BusinessValidation.ValidationCondition(() => !response.GetAssertion().Subject.GetSubjectConfirmation().Method.Equals(SamlConst.Method), string.Format(ErrorLocalization.ParameterNotValid, ErrorFields.Method));
            BusinessValidation.ValidationNotNullNotEmpty(response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData, ErrorFields.SubjectConfirmationData);
            BusinessValidation.ValidationCondition(() => response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.Recipient == null, string.Format(ErrorLocalization.NotSpecified, "Assertion.SubjectConfirmationData.Recipient"));
            BusinessValidation.ValidationCondition(() => string.IsNullOrWhiteSpace(response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.Recipient), string.Format(ErrorLocalization.Missing, "Assertion.SubjectConfirmationData.Recipient"));
            BusinessValidation.ValidationCondition(() => !response.Destination.Equals(response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.Recipient, StringComparison.OrdinalIgnoreCase), ErrorLocalization.InvalidDestination);
            if (!string.IsNullOrWhiteSpace(request.AssertionConsumerServiceURL))
            {
                BusinessValidation.ValidationCondition(() => !response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.Recipient.Equals(request.AssertionConsumerServiceURL), string.Format(ErrorLocalization.DifferentFrom, "Assertion.SubjectConfirmationData.Recipient", "Request"));
            }
            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.InResponseTo, ErrorFields.InResponseTo);
            BusinessValidation.ValidationCondition(() => !response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.InResponseTo.Equals(request.ID), string.Format(ErrorLocalization.ParameterNotValid, ErrorFields.InResponseTo));

            BusinessValidation.ValidationCondition(() => response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.NotOnOrAfter == null, string.Format(ErrorLocalization.NotSpecified, "Assertion.SubjectConfirmationData.NotOnOrAfter"));
            BusinessValidation.ValidationCondition(() => response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.NotOnOrAfter == DateTime.MinValue, string.Format(ErrorLocalization.Missing, "Assertion.SubjectConfirmationData.NotOnOrAfter"));
            DateTimeOffset notOnOrAfter = new DateTimeOffset(response.GetAssertion().Subject.GetSubjectConfirmation().SubjectConfirmationData.NotOnOrAfter);

            BusinessValidation.ValidationCondition(() => notOnOrAfter < DateTimeOffset.UtcNow, ErrorLocalization.NotOnOrAfterLessThenRequest);

            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().Issuer?.Value, ErrorFields.Issuer);
            BusinessValidation.ValidationCondition(() => !response.GetAssertion().Issuer.Value.Equals(metadataIdp.EntityID), string.Format(ErrorLocalization.ParameterNotValid, ErrorFields.Issuer));
            BusinessValidation.ValidationCondition(() => response.GetAssertion().Issuer.Format == null, string.Format(ErrorLocalization.NotSpecified, "Assertion.Issuer.Format"));
            BusinessValidation.ValidationCondition(() => string.IsNullOrWhiteSpace(response.GetAssertion().Issuer.Format), string.Format(ErrorLocalization.Missing, "Assertion.Issuer.Format"));
            BusinessValidation.ValidationCondition(() => !response.GetAssertion().Issuer.Format.Equals(request.Issuer.Format), string.Format(ErrorLocalization.ParameterNotValid, ErrorFields.Format));

            BusinessValidation.ValidationCondition(() => response.GetAssertion().Conditions == null, string.Format(ErrorLocalization.NotSpecified, "Assertion.Conditions"));
            BusinessValidation.ValidationCondition(() => response.GetAssertion().Conditions.GetAudienceRestriction() == null && string.IsNullOrWhiteSpace(response.GetAssertion().Conditions.NotBefore) && string.IsNullOrWhiteSpace(response.GetAssertion().Conditions.NotOnOrAfter), string.Format(ErrorLocalization.Missing, "Assertion.Conditions"));

            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().Conditions.NotOnOrAfter, ErrorFields.NotOnOrAfter);
            DateTimeOffset notOnOrAfterCondition = SamlDefaultSettings.ParseExact(response.GetAssertion().Conditions.NotOnOrAfter, "Assertion.Conditions.NotOnOrAfter");

            BusinessValidation.ValidationCondition(() => notOnOrAfterCondition < DateTimeOffset.UtcNow, ErrorLocalization.NotOnOrAfterLessThenRequest);


            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().Conditions.NotBefore, ErrorFields.NotBefore);
            DateTimeOffset notBefore = SamlDefaultSettings.ParseExact(response.GetAssertion().Conditions.NotBefore, "Assertion.Conditions.NotBefore");

            BusinessValidation.ValidationCondition(() => notBefore > DateTimeOffset.UtcNow, ErrorLocalization.NotBeforeGreaterThenRequest);

            BusinessValidation.ValidationCondition(() => response.GetAssertion().Conditions.GetAudienceRestriction() == null, string.Format(ErrorLocalization.Missing, "Assertion.Conditions.AudienceRestriction"));
            BusinessValidation.ValidationNotNullNotWhitespace(response.GetAssertion().Conditions.GetAudienceRestriction().Audience?.First(), ErrorFields.Audience);
            BusinessValidation.ValidationCondition(() => !(response.GetAssertion().Conditions.GetAudienceRestriction().Audience.First()?.Equals(request.Issuer.Value) ?? false), string.Format(ErrorLocalization.ParameterNotValid, ErrorFields.Audience));

            BusinessValidation.ValidationCondition(() => response.GetAssertion().GetAuthnStatement() == null, string.Format(ErrorLocalization.NotSpecified, ErrorFields.AuthnStatement));
            BusinessValidation.ValidationCondition(() => response.GetAssertion().GetAuthnStatement().AuthnInstant == DateTime.MinValue && string.IsNullOrWhiteSpace(response.GetAssertion().GetAuthnStatement().SessionIndex) && response.GetAssertion().GetAuthnStatement().AuthnContext == null, string.Format(ErrorLocalization.Missing, ErrorFields.AuthnStatement));
            BusinessValidation.ValidationNotNull(response.GetAssertion().GetAuthnStatement().AuthnContext, ErrorFields.AuthnContext);
            BusinessValidation.ValidationNotNull(response.GetAssertion().GetAuthnStatement().AuthnContext.Items, ErrorFields.AuthnContext);
            BusinessValidation.ValidationNotNull(response.GetAssertion().GetAuthnStatement().AuthnContext.ItemsElementName, ErrorFields.AuthnContext);
            BusinessValidation.ValidationCondition(() => response.GetAssertion().GetAuthnStatement().AuthnContext.GetAuthnContextClassRef() == null, string.Format(ErrorLocalization.NotSpecified, "AuthnStatement.AuthnContext.AuthnContextClassRef"));
            BusinessValidation.ValidationCondition(() => string.IsNullOrWhiteSpace(response.GetAssertion().GetAuthnStatement().AuthnContext.GetAuthnContextClassRef()), string.Format(ErrorLocalization.Missing, "AuthnStatement.AuthnContext.AuthnContextClassRef"));
            BusinessValidation.ValidationCondition(() => !response.GetAssertion().GetAuthnStatement().AuthnContext.GetAuthnContextClassRef().Equals(request.RequestedAuthnContext.Items[0]), string.Format(ErrorLocalization.ParameterNotValid, ErrorFields.AuthnContextClassRef));

            BusinessValidation.ValidationCondition(() => !listAuthRefValid.Contains(response.GetAssertion().GetAuthnStatement().AuthnContext.GetAuthnContextClassRef()), string.Format(ErrorLocalization.ParameterNotValid, ErrorFields.AuthnContextClassRef));
        }
Exemplo n.º 22
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);
        }
Exemplo n.º 23
0
        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();
        }
Exemplo n.º 24
0
        public SamlBodyRequest GetSamlRequest(Dictionary <CCAtributes, bool> CCRequestAttrs)
        {
            #region SAML initial request configs
            AuthnRequestType _request = new AuthnRequestType();

            // saml-core-2.0-os - 3.2.1
            // An identifier for the request. It is of type xs:ID and MUST follow the requirements specified in Section
            // 1.3.4 for identifier uniqueness. The values of the ID attribute in a request and the InResponseTo
            // attribute in the corresponding response MUST match
            _request.ID = "_" + Guid.NewGuid().ToString();

            // saml-core-2.0-os - 3.2.1
            // The version of this request. The identifier for the version of SAML defined in this specification is "2.0".
            // SAML versioning is discussed in Section 4.
            _request.Version = "2.0";

            // saml-core-2.0-os - 3.2.1
            // The time instant of issue of the request. The time value is encoded in UTC, as described in Section
            // 1.3.3.
            _request.IssueInstant = DateTime.UtcNow;

            // saml-core-2.0-os - 3.2.1
            // A URI reference indicating the address to which this request has been sent. This is useful to prevent
            // malicious forwarding of requests to unintended recipients, a protection that is required by some
            // protocol bindings. If it is present, the actual recipient MUST check that the URI reference identifies the
            // location at which the message was received. If it does not, the request MUST be discarded. Some
            // protocol bindings may require the use of this attribute (see [SAMLBind]).
            _request.Destination = appSettings.Get("AuthGovPT.Saml.Request.Destination.Url");

            // saml-core-2.0-os - 3.2.1
            // Indicates whether or not (and under what conditions) consent has been obtained from a principal in
            // the sending of this request. See Section 8.4 for some URI references that MAY be used as the value
            // of the Consent attribute and their associated descriptions. If no Consent value is provided, the
            // identifier urn:oasis:names:tc:SAML:2.0:consent:unspecified (see Section 8.4.1) is in
            // effect.
            _request.Consent = "urn:oasis:names:tc:SAML:2.0:consent:unspecified";

            // saml-core-2.0-os - 3.4.1
            // A URI reference that identifies a SAML protocol binding to be used when returning the <Response>
            // message. See [SAMLBind] for more information about protocol bindings and URI references defined
            // for them. This attribute is mutually exclusive with the AssertionConsumerServiceIndex attribute
            // and is typically accompanied by the AssertionConsumerServiceURL attribute.
            _request.ProtocolBinding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";

            // saml-core-2.0-os - 3.4.1
            // Specifies by value the location to which the <Response> message MUST be returned to the
            // requester. The responder MUST ensure by some means that the value specified is in fact associated
            // with the requester. [SAMLMeta] provides one possible mechanism; signing the enclosing
            // <AuthnRequest> message is another. This attribute is mutually exclusive with the
            // AssertionConsumerServiceIndex attribute and is typically accompanied by the
            // ProtocolBinding attribute.
            _request.AssertionConsumerServiceURL = appSettings.Get("AuthGovPT.Saml.Request.AssertionService.Url");

            // saml-core-2.0-os - 3.4.1
            // Specifies the human-readable name of the requester for use by the presenter's user agent or the
            // identity provider.
            _request.ProviderName = appSettings.Get("AuthGovPT.Saml.Request.Provider.Name");

            // saml-core-2.0-os - 2.2.5
            // The <Issuer> element, with complex type NameIDType, provides information about the issuer of a
            // SAML assertion or protocol message. The element requires the use of a string to carry the issuer's name,
            // but permits various pieces of descriptive data (see Section 2.2.2).
            _request.Issuer = new NameIDType();

            _request.Issuer.Value = appSettings.Get("AuthGovPT.Saml.Request.Issuer.Value");


            // saml-core-2.0-os - 3.2.1
            // This extension point contains optional protocol message extension elements that are agreed on
            // between the communicating parties. No extension schema is required in order to make use of this
            // extension point, and even if one is provided, the lax validation setting does not impose a requirement
            // for the extension to be valid. SAML extension elements MUST be namespace-qualified in a non-
            // SAML-defined namespace.
            _request.Extensions = new ExtensionsType();
            #endregion

            #region Load Cartão de Cidadão Attributes

            _request.Extensions.Any = CCAttributes.RegisterCCAtributes(CCRequestAttrs, EnableAuthWithCMD);

            #endregion

            #region SAML Xml convert to stream

            XmlDocument doc = null;

            // Converter objeto para XmlDocument via stream usando serialização com os tipos AuthnRequestType e XmlDocument
            // http://support.microsoft.com/kb/815813/en-us
            try
            {
                MemoryStream  stream            = new MemoryStream();
                XmlSerializer requestSerializer = new XmlSerializer(_request.GetType());
                requestSerializer.Serialize(stream, _request, xmlNamespaces);
                stream.Flush();

                StreamReader reader = new StreamReader(stream);
                stream.Seek(0, SeekOrigin.Begin);
                XmlTextReader xmlReader = new XmlTextReader(new StringReader(reader.ReadToEnd()));

                XmlSerializer xmlDocumentSerializer = new XmlSerializer(typeof(XmlDocument));
                doc = (XmlDocument)xmlDocumentSerializer.Deserialize(xmlReader);
                doc.PreserveWhitespace = true;
            }
            catch (Exception ex)
            {
                //log
                SamlBodyRequest.Success      = false;
                SamlBodyRequest.ErrorMessage = $"Error on XmlDocument object convertion. EX: {ex.ToString()} ";
            }

            #endregion

            #region SAML Xml Signning

            try
            {
                XmlElement element   = doc.DocumentElement;
                SignedXml  signedXml = new SignedXml(element)
                {
                    SigningKey = FaX509Certificate.PrivateKey
                };

                // Tipo de dados "ID" é restrito às strings em NCName:
                //<xs:simpleType name="ID" id="ID">
                //  <xs:annotation>
                //    <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#ID"/>
                //  </xs:annotation>
                //  <xs:restriction base="xs:NCName"/>
                //</xs:simpleType>
                // NCName está definido em http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName como:
                // NCName	 ::=	(Letter | '_') (NCNameChar)*
                Reference reference = new Reference("#" + element.Attributes["ID"].Value);

                // Vide 5.4.3 "Canonicalization Method" e 5.4.4 "Transforms" em
                // http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf

                reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
                reference.AddTransform(new XmlDsigExcC14NTransform());

                signedXml.AddReference(reference);
                signedXml.KeyInfo.AddClause(new KeyInfoX509Data(FaX509Certificate));
                signedXml.ComputeSignature();
                XmlElement xmlDigitalSignature = signedXml.GetXml();

                // AuthnRequestType define a ordem dos elementos filhos na schema saml-schema-protocol-2.0.xsd:
                //<complexType name="RequestAbstractType" abstract="true">
                //    <sequence>
                //        <element ref="saml:Issuer" minOccurs="0"/>
                //        <element ref="ds:Signature" minOccurs="0"/>
                //        <element ref="ds:Signature" minOccurs="0"/>
                //        <element ref="samlp:Extensions" minOccurs="0"/>
                //    </sequence>
                //    ...
                //</complexType>
                XmlNode refNode = doc.GetElementsByTagName("Issuer", "urn:oasis:names:tc:SAML:2.0:assertion").Item(0);
                element.InsertAfter(xmlDigitalSignature, refNode);
            }
            catch (Exception ex)
            {
                //TODO:: log exception ex
                SamlBodyRequest.Success      = false;
                SamlBodyRequest.ErrorMessage = $"Error on Xml signing process. EX: {ex.ToString()}";
            }

            #endregion

            #region Return SAML Request into Auth.gov FA

            SamlBodyRequest.RelayState     = RelayStateToBepersistedAcross;
            SamlBodyRequest.SAMLRequest    = Convert.ToBase64String(Encoding.UTF8.GetBytes(doc.OuterXml));
            SamlBodyRequest.PostRequestUrl = appSettings.Get("AuthGovPT.Saml.Request.Post.Url");

            SamlBodyRequest.Success = true;
            return(SamlBodyRequest);

            // Vide 3.5.3 "RelayState" em
            // http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
            // "...The value MUST NOT exceed 80 bytes in length and SHOULD be integrity protected by the entity
            // creating the message independent of any other protections that may or may not exist during message
            // transmission..."
            // Vide 3.5 "HTTP POST Binding" em
            // http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf

            #endregion
        }
Exemplo n.º 25
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);
        }
        protected virtual NameIDPolicyValidationResult CheckNameIDPolicy(RelyingPartyAggregate relyingParty, User user, AuthnRequestType authnRequest)
        {
            var    attributes   = ConvertAttributes(relyingParty, user);
            string nameIdFormat = Saml.Constants.NameIdentifierFormats.EntityIdentifier;
            string nameIdValue  = user.Claims.First(c => c.Type == Jwt.Constants.UserClaims.Subject).Value;

            if (authnRequest.NameIDPolicy != null &&
                (string.IsNullOrWhiteSpace(authnRequest.NameIDPolicy.Format) || authnRequest.NameIDPolicy.Format == Saml.Constants.NameIdentifierFormats.Unspecified))
            {
                var attr = attributes.FirstOrDefault(a => a.AttributeFormat == authnRequest.NameIDPolicy.Format);
                if (attr == null)
                {
                    throw new SamlException(HttpStatusCode.BadRequest, Saml.Constants.StatusCodes.InvalidNameIDPolicy, string.Format(Global.UnknownNameId, authnRequest.NameIDPolicy.SPNameQualifier));
                }

                nameIdFormat = attr.AttributeFormat;
                nameIdValue  = attr.Value;
            }

            return(new NameIDPolicyValidationResult
            {
                NameIdFormat = nameIdFormat,
                NameIdValue = nameIdValue,
                Attributes = attributes
            });
        }
Exemplo n.º 27
0
        private async Task <HandleRequestResult> ValidateAuthenticationResponse(ResponseType response, AuthnRequestType request, AuthenticationProperties properties, string idPName)
        {
            if (response == null)
            {
                if (Options.SkipUnrecognizedRequests)
                {
                    return(HandleRequestResult.SkipHandler());
                }

                return(HandleRequestResult.Fail("No message."));
            }

            if (properties == null && !Options.AllowUnsolicitedLogins)
            {
                return(HandleRequestResult.Fail("Unsolicited logins are not allowed."));
            }

            var idp = Options.IdentityProviders.FirstOrDefault(x => x.Name == idPName);

            var metadataIdp = await DownloadMetadataIDP(idp.OrganizationUrlMetadata);

            response.ValidateAuthnResponse(request, metadataIdp);
            return(null);
        }
Exemplo n.º 28
0
            public async Task <(bool, AuthnRequestType)> HandleRedirectToIdentityProviderForAuthentication(HttpContext context, AuthenticationScheme scheme, SpidOptions options, AuthenticationProperties properties, AuthnRequestType message)
            {
                var redirectContext = new RedirectContext(context, scheme, options, properties, message);
                await _events.RedirectToIdentityProvider(redirectContext);

                return(redirectContext.Handled, (AuthnRequestType)redirectContext.SignedProtocolMessage);
            }
Exemplo n.º 29
0
        /// <summary>
        /// Build a signed SAML authentication request.
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="destination"></param>
        /// <param name="consumerServiceURL"></param>
        /// <param name="securityLevel"></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="identityProvider"></param>
        /// <param name="enviroment"></param>
        /// <returns>Returns a Base64 Encoded String of the SAML request</returns>
        public static string BuildAuthnPostRequest(string uuid, string destination, string consumerServiceURL, int securityLevel,
                                                   X509Certificate2 certificate, IdentityProvider identityProvider, int enviroment)
        {
            if (string.IsNullOrWhiteSpace(uuid))
            {
                throw new ArgumentNullException("The uuid parameter can't be null or empty.");
            }

            if (string.IsNullOrWhiteSpace(destination))
            {
                throw new ArgumentNullException("The destination parameter can't be null or empty.");
            }

            if (string.IsNullOrWhiteSpace(consumerServiceURL))
            {
                throw new ArgumentNullException("The consumerServiceURL parameter can't be null or empty.");
            }

            if (certificate == null)
            {
                throw new ArgumentNullException("The certificate parameter can't be null.");
            }

            if (identityProvider == null)
            {
                throw new ArgumentNullException("The identityProvider parameter can't be null.");
            }

            if (enviroment < 0)
            {
                throw new ArgumentNullException("The enviroment parameter can't be less than zero.");
            }

            DateTime now = DateTime.UtcNow;

            AuthnRequestType authnRequest = new AuthnRequestType
            {
                ID           = "_" + uuid,
                Version      = "2.0",
                IssueInstant = identityProvider.Now(now),
                Destination  = destination,
                AssertionConsumerServiceIndex           = (ushort)enviroment,
                AssertionConsumerServiceIndexSpecified  = true,
                AttributeConsumingServiceIndex          = 1,
                AttributeConsumingServiceIndexSpecified = true,
                ForceAuthn          = (securityLevel > 1),
                ForceAuthnSpecified = (securityLevel > 1),
                Issuer = new NameIDType
                {
                    Value         = consumerServiceURL.Trim(),
                    Format        = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity",
                    NameQualifier = consumerServiceURL
                },
                NameIDPolicy = new NameIDPolicyType
                {
                    Format = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
                },
                Conditions = new ConditionsType
                {
                    NotBefore             = identityProvider.NotBefore(now),
                    NotBeforeSpecified    = true,
                    NotOnOrAfter          = identityProvider.After(now.AddMinutes(10)),
                    NotOnOrAfterSpecified = true
                },
                RequestedAuthnContext = new RequestedAuthnContextType
                {
                    Comparison          = AuthnContextComparisonType.minimum,
                    ComparisonSpecified = true,
                    ItemsElementName    = new ItemsChoiceType7[] { ItemsChoiceType7.AuthnContextClassRef },
                    Items = new string[] { "https://www.spid.gov.it/SpidL" + securityLevel.ToString() }
                }
            };

            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");

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

            XmlWriter     responseWriter     = XmlTextWriter.Create(stringWriter, settings);
            XmlSerializer responseSerializer = new XmlSerializer(authnRequest.GetType());

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

            string samlString = stringWriter.ToString();

            stringWriter.Close();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(samlString);

            XmlElement signature = XmlSigningHelper.SignXMLDoc(doc, certificate, "_" + uuid);

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

            return(Convert.ToBase64String(Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + doc.OuterXml)));
        }
Exemplo n.º 30
0
        /// <summary>
        /// Gets the authentication request.
        /// </summary>
        /// <returns></returns>
        public string GetAuthRequest()
        {
            string   result         = "";
            DateTime requestDatTime = DateTime.UtcNow;
            //New AuthnRequestType
            AuthnRequestType request = new AuthnRequestType();

            request.Version = Options.Version;

            //Unique UUID
            request.ID = "_" + this.Options.UUID;

            //Request DateTime
            request.IssueInstant = requestDatTime;

            //Request Force Authn
            if ((int)Options.SPIDLevel > 1)
            {
                request.ForceAuthn          = true;
                request.ForceAuthnSpecified = true;
            }
            else
            {
                request.ForceAuthn          = false;
                request.ForceAuthnSpecified = true;
            }


            //SSO Destination URI
            request.Destination = this.Options.Destination;

            //Service Provider Assertion Consumer Service Index
            request.AssertionConsumerServiceIndex          = this.Options.AssertionConsumerServiceIndex;
            request.AssertionConsumerServiceIndexSpecified = true;

            //Service Provider Attribute Consumer Service Index
            request.AttributeConsumingServiceIndex          = this.Options.AttributeConsumingServiceIndex;
            request.AttributeConsumingServiceIndexSpecified = true;


            //Service Provider Attribute Consumer Service Index
            request.AttributeConsumingServiceIndex          = this.Options.AttributeConsumingServiceIndex;
            request.AttributeConsumingServiceIndexSpecified = true;

            //Issuer Data
            request.Issuer = new NameIDType()
            {
                Format        = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity",
                Value         = Options.SPUID,
                NameQualifier = Options.SPUID
            };

            request.NameIDPolicy = new NameIDPolicyType()
            {
                Format      = "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
                AllowCreate = true
            };

            //NotRequired
            request.Conditions = new ConditionsType()
            {
                NotBefore             = requestDatTime.Add(this.Options.NotBefore),
                NotBeforeSpecified    = true,
                NotOnOrAfter          = requestDatTime.Add(this.Options.NotOnOrAfter),
                NotOnOrAfterSpecified = true
            };

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

            request.RequestedAuthnContext = requestedAuthn;


            string samlString = "";

            XmlSerializer serializer = new XmlSerializer(request.GetType());

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

                using (XmlWriter writer = XmlWriter.Create(stringWriter, settings))
                {
                    XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
                    namespaces.Add("saml2p", "urn:oasis:names:tc:SAML:2.0:protocol");

                    serializer.Serialize(writer, request, namespaces);

                    samlString = stringWriter.ToString();
                }
            }
            result = samlString;


            return(result);
        }