2010-03-24 103 views
10

尝试使用MyOpenID和Yahoo进行身份验证时,出现“消息签名不正确”异常。DotNetOpenAuth:消息签名不正确

我使用几乎与DotNetOpenAuth 3.4.2

public ActionResult Authenticate(string openid) 
{ 
    var openIdRelyingParty = new OpenIdRelyingParty(); 
    var authenticationResponse = openIdRelyingParty.GetResponse(); 

    if (authenticationResponse == null) 
    { 
     // Stage 2: User submitting identifier 
     Identifier identifier; 

     if (Identifier.TryParse(openid, out identifier)) 
     { 
      var realm = new Realm(Request.Url.Root() + "openid"); 
      var authenticationRequest = openIdRelyingParty.CreateRequest(openid, realm); 
      authenticationRequest.RedirectToProvider(); 
     } 
     else 
     { 
      return RedirectToAction("login", "home"); 
     } 
    } 
    else 
    { 
     // Stage 3: OpenID provider sending assertion response 
     switch (authenticationResponse.Status) 
     { 
      case AuthenticationStatus.Authenticated: 
      { 
       // TODO 
      } 
      case AuthenticationStatus.Failed: 
      { 
       throw authenticationResponse.Exception; 
      } 
     } 
    } 

    return new EmptyResult(); 
} 

做工精细与谷歌,AOL和其他附带的ASP.NET MVC示例代码。然而,雅虎和myOpenID来说落入AuthenticationStatus.Failed情况下,以下情况例外:

DotNetOpenAuth.Messaging.Bindings.InvalidSignatureException: Message signature was incorrect. 
    at DotNetOpenAuth.OpenId.ChannelElements.SigningBindingElement.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\ChannelElements\SigningBindingElement.cs:line 139 
    at DotNetOpenAuth.Messaging.Channel.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\Messaging\Channel.cs:line 992 
    at DotNetOpenAuth.OpenId.ChannelElements.OpenIdChannel.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\ChannelElements\OpenIdChannel.cs:line 172 
    at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\Messaging\Channel.cs:line 386 
    at DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.GetResponse(HttpRequestInfo httpRequestInfo) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\RelyingParty\OpenIdRelyingParty.cs:line 540 

看来,别人有同样的问题:http://trac.dotnetopenauth.net:8000/ticket/172

有谁有解决方法吗?

+0

我也越来越执行此测试时使用DotNetOpenAuth试验台相同的异常:http://test-id.org/RP/POSTAssertion.aspx –

+0

这看起来像一个类似的问题:HTTP:/ /stackoverflow.com/questions/2508327/invalid-message-signature-when-running-openid-provider-on-cluster –

回答

6

原来这是在Web场环境中使用DotNetOpenAuth的一个问题。

当您创建OpenIdRelyingParty时,请确保您在构造函数中传递null。

这会使您的网站进入OpenID无状态或“哑”模式。用户登录的速度稍微慢一些(如果你注意到的话),但是你不必编写IRelyingPartyApplicationStore来允许DotNetOpenAuth在你的场中工作;

var openIdRelyingParty = new OpenIdRelyingParty(null); 
+2

但我怀疑这可能会引入安全漏洞。有人可以确认吗? –

4

我们通过(在DotNetOpenAuth的较新版本IOpenIdApplicationStore)实施IRelyingPartyApplicationStore并加入店里类名到的.config

<dotNetOpenAuth> 
    <openid ...> 
    <relyingParty> 
     ... 
     <store type="some.name.space.MyRelyingPartyApplicationStore, some.assembly"/> 
    </relyingParty> 
    </openid> 
    ... 
</dotNetOpenAuth> 

接口是其它两个接口有五个组成修复了这个问题所有成员一起。

/// <summary> 
/// A hybrid of the store interfaces that an OpenID Provider must implement, and 
/// an OpenID Relying Party may implement to operate in stateful (smart) mode. 
/// </summary> 
public interface IOpenIdApplicationStore : ICryptoKeyStore, INonceStore 
{ 
} 

我们使用哑模式作为快速修复来起跑,但最终您可能会想要类似这样的东西。

5

所有这些讨论都是围绕着以下问题:

如何依赖方(RP)确保包含身份验证令牌的请求从OP未来(OpenID提供商),以他转交的用户的请求?

以下步骤解释了它是如何发生的

  1. 用户请求来进行回复方(RP),我们在我们的例子网站
  2. 应用存储与该用户在本地签名的唯一签名(LSS),然后将此签名嵌入到消息中,并将此消息转发给OpenId提供商(OP)
  3. 用户键入他的凭证,然后OP对他的消息进行身份验证,然后转发此消息,该消息仍具有嵌入的签名,回到RP
  4. RP比较被嵌入在消息到处于LSS签名中的签名,并且如果它们匹配RP认证用户

如果LSS消失(以某种方式)消息从OP回来之前有RP无法比较签名,因此无法验证用户身份并引发错误:邮件签名不正确。

哪有LSS消失:

  1. ASP.net刷新应用程序池
  2. 重新启动IIS
  3. 在Web场的消息由应用服务托管的不同服务器上

解决此问题的两种方法:

  1. RP运行在哑模式

    a。它不在本地存储和签名,因此不使用签名比较来确保消息来自他转发给用户进行身份验证的OP。

    b。取而代之的是,一旦RP收到来自OP的认证消息,它就会将消息发送回OP,并要求他检查他是否是对该用户进行认证并且是消息的发起者。如果OP回复是我是这封邮件的创始者,并且我创建了此邮件,则用户通过RP进行身份验证

  2. 实现您自己的持久性存储不会消失,无论ASP.net如何处理流程,很像使用SQL来存储会话状态。