コード例 #1
0
ファイル: SAMLEngine.cs プロジェクト: jcaubin/claveOwin
        /// <summary>
        /// Given a SAML request, this function validates it, and extracts the requested attributes.
        /// </summary>
        /// <param name="doc">the xml corresponding to the SAML request</param>
        /// <returns>the context of the SAML request</returns>
        public SAMLContext HandleRequest(XmlDocument xmlRequest)
        {
            try
            {
                int         errorCode;
                SAMLContext context;
                string      issuer = xmlRequest.GetElementsByTagName("Issuer", SAMLConstants.NS_ASSERT).Item(0).InnerText;
                if ((errorCode = Verify(xmlRequest, issuer)) < 0)
                {
                    string assertionConsumer = xmlRequest.GetElementsByTagName("AuthnRequest",
                                                                               SAMLConstants.NS_PROTOCOL).Item(0).Attributes["AssertionConsumerServiceURL"].Value;
                    string requestId = xmlRequest.DocumentElement.Attributes["ID"].Value;
                    context = new SAMLContext(errorCode, requestId, assertionConsumer);
                }
                else
                {
                    context = ExtractRequestValues(xmlRequest);
                }

                return(context);
            }
            catch (Exception ex)
            {
                throw new SAMLException("EXCEPTION HandleRequest", ex);
            }
        }
コード例 #2
0
ファイル: SAMLEngine.cs プロジェクト: jcaubin/claveOwin
        /// <summary>
        /// Generates a SAML response with the given attributes.
        /// </summary>
        /// <param name="attrs"></param>
        /// <returns>the xml corresponding to the SAML response</returns>
        public XmlDocument GenerateResponse(SAMLContext context)
        {
            try
            {
                string      id          = "_" + Guid.NewGuid().ToString();
                XmlDocument xmlResponse = GenerateResponseMetadata(context, id);
                xmlResponse.PreserveWhitespace = true;
                SignatureUtils.SignDocument(xmlResponse, id, certificate,
                                            xmlResponse.GetElementsByTagName("Issuer", SAMLConstants.NS_ASSERT).Item(0));

                return(xmlResponse);
            }
            catch (Exception ex)
            {
                throw new SAMLException("EXCEPTION GenerateResponse", ex);
            }
        }
コード例 #3
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));
        }
コード例 #4
0
ファイル: SAMLEngine.cs プロジェクト: jcaubin/claveOwin
        /// <summary>
        ///
        /// </summary>
        /// <param name="doc"></param>
        /// <returns>a saml context to be used when generating the response</returns>
        private SAMLContext ExtractRequestValues(XmlDocument doc)
        {
            SAMLContext      context = new SAMLContext(SAMLConstants.ErrorCodes.VALID);
            XmlReader        reader  = new XmlTextReader(new StringReader(doc.OuterXml));
            AuthnRequestType request = Deserialize <AuthnRequestType>(reader);

            context.AssertionConsumer = request.AssertionConsumerServiceURL;

            if (IsRepeatedId(request.ID))
            {
                context.ErrorCode = SAMLConstants.ErrorCodes.REPEATED_ID;
                return(context);
            }
            AddId(request.ID);
            if (thisDestination != null && request.Destination != thisDestination)
            {
                context.ErrorCode = SAMLConstants.ErrorCodes.INVALID_DESTINATION;
                return(context);
            }
            if (Math.Abs(request.IssueInstant.Subtract(DateTime.UtcNow).TotalMinutes) > validTimeframe)
            {
                context.ErrorCode = SAMLConstants.ErrorCodes.EXPIRED;
                return(context);
            }

            context.Issuer    = request.Issuer.Value;
            context.RequestID = request.ID;

            XmlElement[] xmlElement    = request.Extensions.Any;
            XmlElement   reqAttributes = null;

            foreach (XmlElement element in xmlElement)
            {
                if (element.LocalName == "RequestedAttributes" &&
                    element.NamespaceURI == ConfigurationSettingsHelper.GetCriticalConfigSetting(CommonConstants.NS_REQ_ATTRS))
                {
                    reqAttributes = element;
                    break;
                }
            }
            if (reqAttributes == null)
            {
                context.ErrorCode = SAMLConstants.ErrorCodes.XML_VALIDATION_FAILED;
                return(context);
            }

            try
            {
                foreach (XmlElement element in reqAttributes.GetElementsByTagName("RequestedAttribute", ConfigurationSettingsHelper.GetCriticalConfigSetting(CommonConstants.NS_REQ_ATTR)))
                {
                    XmlAttributeCollection attrCollection = element.Attributes;
                    string name = attrCollection["Name"].Value;
                    // string nameFormat = attrColection["NameFormat"].Value;
                    string isRequired = attrCollection["isRequired"].Value;
                    context.AddAttribute(name, bool.Parse(isRequired));
                }
            }
            catch (Exception)
            {
                //something wrong happend with the attribute processing.
                //Problably the isRequiredAttribut is not present. Log the event and return an InvalidAttribute response
                context.ErrorCode = SAMLConstants.ErrorCodes.INVALID_ATTRIBUTES;
                return(context);
            }

            if (context.GetAttributeNames().Count == 0)
            {
                context.ErrorCode = SAMLConstants.ErrorCodes.INVALID_ATTRIBUTES;
            }
            return(context);
        }