2010-03-24 87 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來存儲會話狀態。