C# 如何在asp.net中创建shibboleth auth saml请求?

C# 如何在asp.net中创建shibboleth auth saml请求?,c#,asp.net,shibboleth,C#,Asp.net,Shibboleth,我们已经在本地服务器上安装了shibboleth sp和idp,并且使用ldap连接成功登录。现在的问题是,shibboleth sp在iis中使用了*.sso过滤器,我们想删除它,并生成一个c sharp代码stuf,该代码创建对shibboleth idp的saml请求。有什么可能的方法吗 谢谢,我们终于拿到了。 假设我们在登录单击时调用了一个操作方法 public ActionResult submitresult() { AuthRequest req

我们已经在本地服务器上安装了shibboleth sp和idp,并且使用ldap连接成功登录。现在的问题是,shibboleth sp在iis中使用了*.sso过滤器,我们想删除它,并生成一个c sharp代码stuf,该代码创建对shibboleth idp的saml请求。有什么可能的方法吗

谢谢,我们终于拿到了。 假设我们在登录单击时调用了一个操作方法

    public ActionResult submitresult()
    {

        AuthRequest req = new AuthRequest();
        return Redirect("http://myshibboleth.idp.com/idp/profile/SAML2/Redirect/SSO?SAMLRequest=" + Server.UrlEncode(req.GetRequest(AuthRequest.AuthRequestFormat.Base64)));           
    }
这是我的AuthRequest类

public class Certificate
{
    public X509Certificate2 cert;

    public void LoadCertificate()
    {
        string certificate = "-----BEGIN CERTIFICATE-----certificate data -----END CERTIFICATE-----";
        cert = new X509Certificate2(certificate);
        cert.Import(StringToByteArray(certificate));
    }

    public void LoadCertificate(byte[] certificate)
    {
        cert = new X509Certificate2();
        cert.Import(certificate);
    }

    private byte[] StringToByteArray(string st)
    {
        byte[] bytes = new byte[st.Length];
        for (int i = 0; i < st.Length; i++)
        {
            bytes[i] = (byte)st[i];
        }
        return bytes;
    }
}

public class Response
{
    private XmlDocument xmlDoc;

    private Certificate certificate;
    public Response()
    {

        certificate = new Certificate();
        certificate.LoadCertificate();
    }

    public void LoadXml(string xml)
    {
        xmlDoc = new XmlDocument();
        xmlDoc.PreserveWhitespace = true;
        xmlDoc.XmlResolver = null;
        xmlDoc.LoadXml(xml);
    }

    public void LoadXmlFromBase64(string response)
    {
        System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
        LoadXml(enc.GetString(Convert.FromBase64String(response)));
    }

    public bool IsValid()
    {
        bool status = true;

        XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable);
        manager.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
        manager.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
        manager.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
        XmlNodeList nodeList = xmlDoc.SelectNodes("//ds:Signature", manager);

        SignedXml signedXml = new SignedXml(xmlDoc);
        signedXml.LoadXml((XmlElement)nodeList[0]);

        status &= signedXml.CheckSignature(certificate.cert, true);

        var notBefore = NotBefore();
        status &= !notBefore.HasValue || (notBefore <= DateTime.Now);

        var notOnOrAfter = NotOnOrAfter();
        status &= !notOnOrAfter.HasValue || (notOnOrAfter > DateTime.Now);

        return status;
    }

    public DateTime? NotBefore()
    {
        XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable);
        manager.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
        manager.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");

        var nodes = xmlDoc.SelectNodes("/samlp:Response/saml:Assertion/saml:Conditions", manager);
        string value = null;
        if (nodes != null && nodes.Count > 0 && nodes[0] != null && nodes[0].Attributes != null && nodes[0].Attributes["NotBefore"] != null)
        {
            value = nodes[0].Attributes["NotBefore"].Value;
        }
        return value != null ? DateTime.Parse(value) : (DateTime?)null;
    }

    public DateTime? NotOnOrAfter()
    {
        XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable);
        manager.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
        manager.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");

        var nodes = xmlDoc.SelectNodes("/samlp:Response/saml:Assertion/saml:Conditions", manager);
        string value = null;
        if (nodes != null && nodes.Count > 0 && nodes[0] != null && nodes[0].Attributes != null && nodes[0].Attributes["NotOnOrAfter"] != null)
        {
            value = nodes[0].Attributes["NotOnOrAfter"].Value;
        }
        return value != null ? DateTime.Parse(value) : (DateTime?)null;
    }

    public string GetNameID()
    {
        XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable);
        manager.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
        manager.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
        manager.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");

        XmlNode node = xmlDoc.SelectSingleNode("/samlp:Response/saml:Assertion/saml:Subject/saml:NameID", manager);
        return node.InnerText;
    }
}

public class AuthRequest
{
    public string id;
    private string issue_instant;


    public enum AuthRequestFormat
    {
        Base64 = 1
    }

    public AuthRequest()
    {

        id = "_" + System.Guid.NewGuid().ToString();
        issue_instant = DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ");
    }

    public string GetRequest(AuthRequestFormat format)
    {
        using (StringWriter sw = new StringWriter())
        {
            XmlWriterSettings xws = new XmlWriterSettings();
            xws.OmitXmlDeclaration = true;

            using (XmlWriter xw = XmlWriter.Create(sw, xws))
            {
                xw.WriteStartElement("samlp", "AuthnRequest", "urn:oasis:names:tc:SAML:2.0:protocol");
                xw.WriteAttributeString("ID", id);
                xw.WriteAttributeString("Version", "2.0");
                xw.WriteAttributeString("IssueInstant", issue_instant);
                xw.WriteAttributeString("ProtocolBinding", "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
                xw.WriteAttributeString("AssertionConsumerServiceURL", "http://localhost/SAML2/POST"); // service provider url to consume token . it should be post method
                xw.WriteAttributeString("Destination", "http://myshibboleth.idp.com/idp/profile/SAML2/Redirect/SSO");

                //xw.WriteAttributeString("AssertionConsumerServiceURL", ConfigurationManager.AppSettings["AssertionConsumerServiceURL"]);
                //xw.WriteAttributeString("Destination", ConfigurationManager.AppSettings["Destination"]);


                xw.WriteStartElement("saml", "Issuer", "urn:oasis:names:tc:SAML:2.0:assertion");
                xw.WriteString("http://localhost");  // service provider home url
                xw.WriteEndElement();

                xw.WriteStartElement("samlp", "NameIDPolicy", "urn:oasis:names:tc:SAML:2.0:protocol");

                xw.WriteAttributeString("AllowCreate", "true");
                xw.WriteEndElement();

                //xw.WriteStartElement("samlp", "RequestedAuthnContext", "urn:oasis:names:tc:SAML:2.0:protocol");
                //xw.WriteAttributeString("Comparison", "exact");

                //xw.WriteStartElement("saml", "AuthnContextClassRef", "urn:oasis:names:tc:SAML:2.0:assertion");
                //xw.WriteString("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport");
                //xw.WriteEndElement();

                xw.WriteEndElement(); // RequestedAuthnContext


            }

            if (format == AuthRequestFormat.Base64)
            {

                var bytes = Encoding.UTF8.GetBytes(sw.ToString());
                using (var output = new MemoryStream())
                {
                    using (var zip = new DeflateStream(output, CompressionMode.Compress))
                    {
                        zip.Write(bytes, 0, bytes.Length);
                    }
                    var base64 = Convert.ToBase64String(output.ToArray());
                    return base64;
                    //return HttpUtility.UrlEncode(base64);
                }
            }

            return null;
        }
    }
}
公共类证书
{
公开X509证书2证书;
公共证书()
{
字符串certificate=“-----开始证书------证书数据------结束证书------”;
证书=新的X509Certificate2(证书);
cert.Import(StringToByteArray(证书));
}
公共无效加载证书(字节[]证书)
{
证书=新的X509Certificate2();
进口证书(证书);
}
专用字节[]StringToByteArray(字符串st)
{
字节[]字节=新字节[st.Length];
对于(int i=0;i0&&nodes[0]!=null&&nodes[0]。属性!=null&&nodes[0]。属性[“NotBefore”]!=null)
{
值=节点[0]。属性[“NotBefore”]。值;
}
返回值!=null?DateTime.Parse(值):(DateTime?)null;
}
public DateTime?NotOnOrAfter()
{
XmlNamespaceManager=newxmlnamespacemanager(xmlDoc.NameTable);
AddNamespace(“saml”,“urn:oasis:names:tc:saml:2.0:assertion”);
AddNamespace(“samlp”,“urn:oasis:names:tc:SAML:2.0:protocol”);
var nodes=xmlDoc.SelectNodes(“/samlp:Response/saml:Assertion/saml:Conditions”,manager);
字符串值=null;
if(nodes!=null&&nodes.Count>0&&nodes[0]!=null&&nodes[0]。Attributes!=null&&nodes[0]。Attributes[“NotOnOrAfter”]!=null)
{
值=节点[0]。属性[“NONONOR”]。值;
}
返回值!=null?DateTime.Parse(值):(DateTime?)null;
}
公共字符串GetNameID()
{
XmlNamespaceManager=newxmlnamespacemanager(xmlDoc.NameTable);
manager.AddNamespace(“ds”,SignedXml.XmlDsigNamespaceUrl);
AddNamespace(“saml”,“urn:oasis:names:tc:saml:2.0:assertion”);
AddNamespace(“samlp”,“urn:oasis:names:tc:SAML:2.0:protocol”);
XmlNode node=xmlDoc.SelectSingleNode(“/samlp:Response/saml:Assertion/saml:Subject/saml:NameID”,manager);
返回node.InnerText;
}
}
公共类AuthRequest
{
公共字符串id;
私有字符串问题(u instant);;
公共枚举AuthRequestFormat
{
Base64=1
}
公共授权请求()
{
id=“389;”+System.Guid.NewGuid().ToString();
issue_instant=DateTime.Now.ToUniversalTime().ToString(“yyyy-MM-ddTHH:MM:ssZ”);
}
公共字符串GetRequest(AuthRequestFormat格式)
{
使用(StringWriter sw=new StringWriter())
{
XmlWriterSettings xws=新的XmlWriterSettings();
xws.OmitXmlDeclaration=true;
使用(xmlwriterxw=XmlWriter.Create(sw,xws))
{
writeStarteElement(“samlp”、“AuthnRequest”、“urn:oasis:names:tc:SAML:2.0:protocol”);
WriteAttributeString(“ID”,ID);
WriteAttributeString(“版本”,“2.0”);
WriteAttributeString(“IssueInstant”,issue\u instant);
WriteAttributeString(“ProtocolBinding”,“urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST”);
WriteAttributeString(“AssertionConsumerServiceURL”http://localhost/SAML2/POST“”;//使用令牌的服务提供程序url。它应该是post方法
xw.WriteAttributeString(“目的地”http://myshibboleth.idp.com/idp/profile/SAML2/Redirect/SSO");
//WriteAttributeString(“AssertionConsumerServiceURL”,ConfigurationManager.AppSettings[“AssertionConsumerServiceURL]”);
//xw.WriteAttributeString(“目的地”,ConfigurationManager.AppSettings[“目的地