C# 如何在asp.net中创建shibboleth auth saml请求?
我们已经在本地服务器上安装了shibboleth sp和idp,并且使用ldap连接成功登录。现在的问题是,shibboleth sp在iis中使用了*.sso过滤器,我们想删除它,并生成一个c sharp代码stuf,该代码创建对shibboleth idp的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
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[“目的地