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
有人有解決方法嗎?
原來這是在網路農場環境中使用 DotNetOpenAuth 的問題。
創建 OpenIdRelyingParty 時,請確保在建構子中傳遞 null。
這會將您的網站置於 OpenID 無狀態或“啞”模式。使用者登錄的速度稍慢(如果您注意到的話),但您不必編寫 IRelyingPartyApplicationStore 以允許 DotNetOpenAuth 在您的農場中工作;
var openIdRelyingParty = new OpenIdRelyingParty(null);
所有這些討論都圍繞以下問題:
依賴方 (RP) 如何確保包含身份驗證令牌的請求來自他將使用者請求轉發到的 OP(OpenId 提供者)?
以下步驟解釋了它是如何發生的
- 使用者請求到達回複方 (RP),在我們的案例中是我們的網站
- 應用程序將與該使用者對應的唯一簽名儲存在本地簽名儲存(LSS)中,然後將該簽名嵌入到消息中並將該消息轉發給OpenId Provider(OP)
- 使用者鍵入他的憑據,OP 驗證他的消息,然後將該消息(其中仍嵌入簽名)轉發回 RP
- RP 將嵌入在消息中的簽名與 LSS 中的簽名進行比較,如果它們匹配 RP,則對使用者進行身份驗證
如果 LSS 在消息從 OP 返回之前消失(不知何故),則 RP 無法將簽名與之進行比較,因此它無法驗證使用者並拋出錯誤:消息簽名不正確。
LSS 如何消失:
- ASP.net 刷新應用程序池
- IIS 重新啟動
- 在網路農場中,消息由託管在不同伺服器上的應用程序提供服務
這個問題的兩個解決方案:
- RP 在啞模式下執行
**一種。**它不在本地儲存和簽名,因此不使用簽名比較來確保消息來自他將使用者轉發到以進行身份驗證的 OP
**灣。**相反,一旦 RP 從 OP 接收到身份驗證消息,它就會將消息發送回 OP 並要求他檢查他是否是驗證此使用者的人並且是消息的發起者。如果 OP 回復是,我是此消息的發起者並且我已創建此消息,則使用者已通過 RP 身份驗證 2. 實現您自己的不會消失的持久性儲存,無論 ASP.net 對程序做什麼,就像使用 SQL 儲存會話狀態一樣。