DotNetOpenAuth:邮件签名不正确

时间:2010-03-24 05:32:36

标签: asp.net-mvc openid yahoo dotnetopenauth

尝试使用MyOpenID和Yahoo进行身份验证时,我收到“邮件签名不正确”的异常。

我正在使用DotNetOpenAuth 3.4.2附带的ASP.NET MVC示例代码

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

与Google,AOL和其他人合作。但是,Yahoo和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

有没有人有解决方法?

3 个答案:

答案 0 :(得分:6)

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

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

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

var openIdRelyingParty = new OpenIdRelyingParty(null);

答案 1 :(得分:5)

所有这些讨论都围绕以下问题展开:

依赖方(RP)如何确保包含身份验证令牌的请求来自他将用户请求转发给的OP(OpenId Provider)?

以下步骤说明了它是如何发生的

  1. 用户请求来到回复方(RP),我们的网站就是
  2. 应用程序将对应于此用户的唯一签名存储在本地签名存储(LSS)中,然后将此签名嵌入到消息中并将此消息转发给OpenId Provider(OP)
  3. 用户输入他的凭据,OP对其消息进行身份验证,然后转发此消息,该消息仍然嵌入其中,返回RP
  4. RP将消息中嵌入的签名与LSS中的签名进行比较,如果它们与RP匹配则对用户进行身份验证
  5. 如果LSS在消息从OP返回之前消失(某种程度上),则RP没有任何内容可以比较签名,因此无法对用户进行身份验证并抛出错误:消息签名不正确。

    LSS如何消失:

    1. ASP.net刷新应用程序池
    2. IIS重新启动
    3. 在Web场中,Message由托管在不同服务器上的应用程序提供服务
    4. 这个问题的两个解决方案:

      1. RP以哑模式运行

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

        b。相反,一旦RP收到来自OP的身份验证消息,它就会将消息发送回OP并要求他检查他是否是对该用户进行身份验证的人并且是消息。如果OP回复是,我是此消息的发起人,我创建了此消息,然后用户通过RP验证

      2. 实现你自己的持久性存储,它不会消失,无论ASP.net对进程做什么,就像使用SQL存储会话状态一样。

答案 2 :(得分:4)

我们通过在较新版本的DotNetOpenAuth中实施IRelyingPartyApplicationStoreIOpenIdApplicationStore)并将商店类名称添加到.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
{
}

我们使用哑模式作为快速修复来启动跑步,但最终你可能想要这样的东西。