Asp.net mvc 4 在Windows身份基础中调试SAML令牌解析错误
我正在寻找在使用WIF时解决SAML令牌解析错误的方法。我对这项技术相当陌生,所以我可能缺少一些明显的技术 我编写了一个示例MVC应用程序,它使用WS-Federation进行外部身份验证。 我在本地用ThinkTecture服务器试用了一下,效果非常好。然而,当我在外部STS服务器(CA CloudMinder)上尝试相同的方法时,我在WIF中遇到了以下错误:Asp.net mvc 4 在Windows身份基础中调试SAML令牌解析错误,asp.net-mvc-4,wif,saml-2.0,ws-federation,Asp.net Mvc 4,Wif,Saml 2.0,Ws Federation,我正在寻找在使用WIF时解决SAML令牌解析错误的方法。我对这项技术相当陌生,所以我可能缺少一些明显的技术 我编写了一个示例MVC应用程序,它使用WS-Federation进行外部身份验证。 我在本地用ThinkTecture服务器试用了一下,效果非常好。然而,当我在外部STS服务器(CA CloudMinder)上尝试相同的方法时,我在WIF中遇到了以下错误: Application Error: 'Element' is an invalid XmlNodeType. System.Xml.
Application Error: 'Element' is an invalid XmlNodeType. System.Xml.XmlException XmlException System.Xml.XmlException: 'Element' is an invalid XmlNodeType.
at System.Xml.XmlReader.ReadEndElement()
at System.IdentityModel.Tokens.Saml2SecurityTokenHandler.ReadAssertion(XmlReader reader)
at System.IdentityModel.Tokens.Saml2SecurityTokenHandler.ReadToken(XmlReader reader)
at System.IdentityModel.Tokens.SecurityTokenHandlerCollection.ReadToken(XmlReader reader)
at System.IdentityModel.Services.TokenReceiver.ReadToken(String tokenXml, XmlDictionaryReaderQuotas readerQuotas, FederationConfiguration federationConfiguration)
at System.IdentityModel.Services.WSFederationAuthenticationModule.SignInWithResponseMessage(HttpRequestBase request)
at System.IdentityModel.Services.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) Void ReadEndElement() at System.Xml.XmlReader.ReadEndElement()
at System.IdentityModel.Tokens.Saml2SecurityTokenHandler.ReadAssertion(XmlReader reader)
at System.IdentityModel.Tokens.Saml2SecurityTokenHandler.ReadToken(XmlReader reader)
at System.IdentityModel.Tokens.SecurityTokenHandlerCollection.ReadToken(XmlReader reader)
at System.IdentityModel.Services.TokenReceiver.ReadToken(String tokenXml, XmlDictionaryReaderQuotas readerQuotas, FederationConfiguration federationConfiguration)
at System.IdentityModel.Services.WSFederationAuthenticationModule.SignInWithResponseMessage(HttpRequestBase request)
at System.IdentityModel.Services.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
很明显,这和被发回的实际SAML令牌的格式有关。
我想我可以按如下方式捕获令牌本身并记录它:
void WSFederationAuthenticationModule_SignInError(object sender, ErrorEventArgs e)
{
var message = FederatedAuthentication.WSFederationAuthenticationModule.GetSignInResponseMessage(
new HttpRequestWrapper(HttpContext.Current.Request));
}
我无法共享实际令牌本身。但是我想知道,您是否知道如何解决这些错误的方法,例如手动验证令牌的方法
任何建议都值得赞赏。好的,因此我使用的一种技术被证明对缩小问题范围非常有用,那就是对我自己的
Saml2SecurityTokenHandler
进行子类化和注册
这有助于我验证问题是在SAML令牌中元素的顺序中出现的-显然,WIF在SAML断言中签名元素的位置方面不是很宽容-它要求它紧跟在Issuer元素之后
public class ForgivingSaml2SecurityTokenHandler : Saml2SecurityTokenHandler
{
public override SecurityToken ReadToken(XmlReader reader)
{
reader = SanitizeToken(reader);
return base.ReadToken(reader);
}
XmlReader SanitizeToken(XmlReader reader)
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
var ns = new XmlNamespaceManager(xmlDoc.NameTable);
ns.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
ns.AddNamespace("sa", "urn:oasis:names:tc:SAML:2.0:assertion");
var issuerNode = xmlDoc.SelectSingleNode("//sa:Issuer", ns);
var signatureNode = xmlDoc.SelectSingleNode("//ds:Signature", ns);
signatureNode.ParentNode.InsertAfter(signatureNode, issuerNode);
string sanitizedToken = xmlDoc.InnerXml;
return new XmlTextReader(new StringReader(sanitizedToken));
}
}
因此,上述方法并不能真正解决问题,因为修改令牌导致签名检查失败,但它允许我验证订单确实是问题所在,因为我能够修改正确的令牌并使其以与问题令牌相同的方式失败-显然,令牌结构检查是在WIF进行签名检查之前执行的
为了注册我的子类令牌处理程序,我在web.config文件中使用了以下注册:
<identityConfiguration saveBootstrapContext="true">
<securityTokenHandlers>
<remove type="System.IdentityModel.Tokens.Saml2SecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add type="ExploringSaml.ForgivingSaml2SecurityTokenHandler, ExploringSaml" ></add>
</securityTokenHandlers>