【问题标题】:Debugging SAML Token Parser errors in Windows Identity Foundation调试 Windows Identity Foundation 中的 SAML 令牌解析器错误
【发布时间】:2014-05-01 07:30:57
【问题描述】:

我正在寻找在使用 WIF 时解决 SAML 令牌解析错误的方法。我对这项技术还很陌生,所以我可能会遗漏一些明显的技术。

我编写了一个使用 WS-Federation 使用外部身份验证的示例 MVC 应用程序。 我在本地使用 ThinkTecture 服务器进行了尝试,它就像一个魅力。但是,当我使用外部 STS 服务器 (CA CloudMinder) 尝试相同的方法时,我在 WIF 中遇到以下错误:

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));
}

我不能分享实际的令牌本身。但我想知道,如果您知道如何解决这些错误的任何方法 - 例如手动验证令牌的某种方法。

任何建议表示赞赏。

【问题讨论】:

    标签: asp.net-mvc-4 wif saml-2.0 ws-federation


    【解决方案1】:

    好的,所以我使用的一种被证明对缩小问题非常有用的技术是子类化​​并注册我自己的Saml2SecurityTokenHandler

    这帮助我验证了问题出在 SAML 令牌中的元素顺序 - 显然 WIF 对 SAML 断言中 Signature 元素的位置不是很宽容 - 它要求它紧跟在 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 2011-01-11
      • 2011-04-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      相关资源
      最近更新 更多