/// <summary>CreateMetadata</summary> /// <param name="entityID">string</param> /// <param name="pemString">string</param> /// <param name="nameIDFormats">SAML2Enum.NameIDFormat[]</param> /// <param name="saml2RequestEndpoint_Redirect">string</param> /// <param name="saml2RequestEndpoint_Post">string</param> /// <returns>SAMLMetadata</returns> public static XmlDocument CreateMetadata( string entityID, string pemString, SAML2Enum.NameIDFormat[] nameIDFormats, string saml2RequestEndpoint_Redirect, string saml2RequestEndpoint_Post) { string xmlString = SAML2Const.MetadataTemplate; #region enum 2 string List <string> urnNameIDFormatsString = new List <string>(); foreach (SAML2Enum.NameIDFormat nameIDFormat in nameIDFormats) { urnNameIDFormatsString.Add(SAML2Enum.EnumToString(nameIDFormat)); } #endregion #region Replace // 固定値 xmlString = xmlString.Replace("{UrnMetadata}", SAML2Const.UrnMetadata); xmlString = xmlString.Replace("{UrnProtocolSupportEnumeration}", SAML2Const.UrnProtocol); xmlString = xmlString.Replace("{SingleSignOnServiceRedirect}", SAML2Const.UrnBindingsRedirect); xmlString = xmlString.Replace("{SingleSignOnServicePost}", SAML2Const.UrnBindingsPost); // 可変値 xmlString = xmlString.Replace("{EntityID}", entityID); xmlString = xmlString.Replace("{WantAuthnRequestsSigned}", "true"); xmlString = xmlString.Replace("{X509CertificatePemString}", pemString); //xmlString = xmlString.Replace("{UrnNameIDFormat}", urnNameIDFormatString); xmlString = xmlString.Replace("{SingleSignOnServiceRedirectLocation}", saml2RequestEndpoint_Redirect); xmlString = xmlString.Replace("{SingleSignOnServicePostLocation}", saml2RequestEndpoint_Post); // XmlDocument化 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = false; xmlDoc.LoadXml(xmlString); #endregion #region Append // 以下は可変要素 XmlNode newNode = null; XmlNode rootNode = xmlDoc.GetElementsByTagName("md:IDPSSODescriptor")[0]; // NameIDFormat foreach (string text in urnNameIDFormatsString) { newNode = xmlDoc.CreateNode( XmlNodeType.Element, "md", "NameIDFormat", SAML2Const.UrnMetadata); // 空のxmlns属性 出力問題の抑止 newNode.InnerText = text; rootNode.AppendChild(newNode); } #endregion return(xmlDoc); }
/// <summary>CreateRequest</summary> /// <param name="issuer">string</param> /// <param name="protocolBinding">SAML2Enum.ProtocolBinding</param> /// <param name="nameIDFormat">SAML2Enum.NameIDFormat</param> /// <param name="assertionConsumerServiceURL">string</param> /// <param name="id">string</param> /// <returns>SAMLRequest</returns> public static XmlDocument CreateRequest(string issuer, SAML2Enum.ProtocolBinding protocolBinding, SAML2Enum.NameIDFormat nameIDFormat, string assertionConsumerServiceURL, out string id) { // idの先頭は[A-Za-z]のみで、s2とするのが慣例っぽい。 id = "s2" + Guid.NewGuid().ToString("N"); string xmlString = SAML2Const.RequestTemplate; #region enum 2 string string urnNameIDFormatString = SAML2Enum.EnumToString(nameIDFormat); string protocolBindingString = SAML2Enum.EnumToString(protocolBinding); #endregion #region Replace // 固定値 xmlString = xmlString.Replace("{UrnProtocol}", SAML2Const.UrnProtocol); xmlString = xmlString.Replace("{UrnAssertion}", SAML2Const.UrnAssertion); // 可変値 // - 共通 xmlString = xmlString.Replace("{ID}", id); xmlString = xmlString.Replace("{Issuer}", issuer); xmlString = xmlString.Replace("{IssueInstant}", FormatConverter.ToW3cTimestamp(DateTime.UtcNow)); // - ... xmlString = xmlString.Replace("{UrnNameIDFormat}", urnNameIDFormatString); // XmlDocument化 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = false; xmlDoc.LoadXml(xmlString); #endregion #region Append // 以下はオプション属性 XmlNode node = xmlDoc.GetElementsByTagName("samlp:AuthnRequest")[0]; XmlAttribute attr = null; // - ProtocolBinding属性 if (!string.IsNullOrEmpty(protocolBindingString)) { attr = xmlDoc.CreateAttribute("ProtocolBinding"); attr.Value = protocolBindingString; node.Attributes.Append(attr); } // - AssertionConsumerServiceURL属性 if (!string.IsNullOrEmpty(assertionConsumerServiceURL)) { attr = xmlDoc.CreateAttribute("AssertionConsumerServiceURL"); attr.Value = assertionConsumerServiceURL; node.Attributes.Append(attr); } #endregion return(xmlDoc); }
/// <summary>CreateResponse</summary> /// <param name="issuer">string</param> /// <param name="destination">string</param> /// <param name="inResponseTo">string</param> /// <param name="statusCode">SAML2Enum.StatusCode</param> /// <param name="id">string</param> /// <returns>SAMLResponse</returns> public static XmlDocument CreateResponse( string issuer, string destination, string inResponseTo, SAML2Enum.StatusCode statusCode, out string id) { // idの先頭は[A-Za-z]のみで、s2とするのが慣例っぽい。 id = "s2" + Guid.NewGuid().ToString("N"); string xmlString = SAML2Const.ResponseTemplate; #region enum 2 string string urnStatusCodeString = SAML2Enum.EnumToString(statusCode); #endregion #region Replace // 固定値 xmlString = xmlString.Replace("{UrnProtocol}", SAML2Const.UrnProtocol); xmlString = xmlString.Replace("{UrnAssertion}", SAML2Const.UrnAssertion); // 可変値 // - 共通 xmlString = xmlString.Replace("{ID}", id); xmlString = xmlString.Replace("{IssueInstant}", FormatConverter.ToW3cTimestamp(DateTime.UtcNow)); xmlString = xmlString.Replace("{Issuer}", issuer); // - Response固有 xmlString = xmlString.Replace("{Destination}", destination); xmlString = xmlString.Replace("{InResponseTo}", inResponseTo); xmlString = xmlString.Replace("{UrnStatusCode}", urnStatusCodeString); // XmlDocument化 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = false; xmlDoc.LoadXml(xmlString); #endregion return(xmlDoc); }
/// <summary>CreateAssertion</summary> /// <param name="inResponseTo">string</param> /// <param name="issuer">string</param> /// <param name="nameID">string</param> /// <param name="nameIDFormat">SAML2Enum.NameIDFormat</param> /// <param name="authnContextClassRef">SAML2Enum.AuthnContextClassRef</param> /// <param name="expiresFromSecond">double</param> /// <param name="recipient">string</param> /// <param name="id">string</param> /// <param name="rsa">RSA</param> /// <returns>SAMLAssertion</returns> public static XmlDocument CreateAssertion( string inResponseTo, string issuer, string nameID, SAML2Enum.NameIDFormat nameIDFormat, SAML2Enum.AuthnContextClassRef authnContextClassRef, double expiresFromSecond, string recipient, out string id, RSA rsa = null) { // idの先頭は[A-Za-z]のみで、s2とするのが慣例っぽい。 id = "s2" + Guid.NewGuid().ToString("N"); string xmlString = SAML2Const.AssertionTemplate; #region enum 2 string string urnNameIDFormatString = SAML2Enum.EnumToString(nameIDFormat); string urnAuthnContextClassRefString = SAML2Enum.EnumToString(authnContextClassRef); #endregion #region Replace // 固定値 xmlString = xmlString.Replace("{UrnProtocol}", SAML2Const.UrnProtocol); xmlString = xmlString.Replace("{UrnAssertion}", SAML2Const.UrnAssertion); xmlString = xmlString.Replace("{UrnMethod}", SAML2Const.UrnMethodBearer); // 可変値 // - ID xmlString = xmlString.Replace("{ID}", id); xmlString = xmlString.Replace("{InResponseTo}", inResponseTo); xmlString = xmlString.Replace("{Issuer}", issuer); // - 認証関連 xmlString = xmlString.Replace("{NameID}", nameID); xmlString = xmlString.Replace("{UrnNameIDFormat}", urnNameIDFormatString); xmlString = xmlString.Replace("{UrnAuthnContextClassRef}", urnAuthnContextClassRefString); // - 時間関連 string utcNow = FormatConverter.ToW3cTimestamp(DateTime.UtcNow); xmlString = xmlString.Replace("{IssueInstant}", utcNow); xmlString = xmlString.Replace("{AuthnInstant}", utcNow); xmlString = xmlString.Replace("{NotBefore}", utcNow); string utcExpires = FormatConverter.ToW3cTimestamp(DateTime.UtcNow.AddSeconds(expiresFromSecond)); xmlString = xmlString.Replace("{NotOnOrAfter}", utcExpires); // - SP関連 xmlString = xmlString.Replace("{Recipient}", recipient); xmlString = xmlString.Replace("{Audience}", recipient); // recipientのFQDNまでらしい // XmlDocument化 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = false; xmlDoc.LoadXml(xmlString); #endregion #region Sign if (rsa != null) { SignedXml2 signedXml2 = new SignedXml2(rsa); xmlDoc = signedXml2.Create(xmlDoc, id); } #endregion return(xmlDoc); }