2010-03-24 10 views
10

Tôi nhận được ngoại lệ "Chữ ký thư không chính xác" khi cố gắng xác thực với MyOpenID và Yahoo.DotNetOpenAuth: Chữ ký thư không chính xác

Tôi đang sử dụng khá nhiều ASP.NET MVC mẫu mã đi kèm với 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(); 
} 

Làm việc tốt với Google, AOL và những người khác. Tuy nhiên, Yahoo và Myopenid rơi vào trường hợp AuthenticationStatus.Failed với ngoại lệ sau đây:

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 

Xuất hiện mà những người khác đang có cùng một vấn đề: http://trac.dotnetopenauth.net:8000/ticket/172

Có ai có một cách giải quyết?

+0

Tôi cũng nhận được cùng một ngoại lệ sử dụng băng ghế dự bị kiểm tra DotNetOpenAuth khi thực hiện xét nghiệm này: http://test-id.org/RP/POSTAssertion.aspx –

+0

này trông giống như một vấn đề tương tự: http://stackoverflow.com/questions/2508327/invalid-message-signature-when-running-openid-provider-on-cluster –

Trả lời

6

Hóa ra đây là vấn đề khi sử dụng DotNetOpenAuth trong môi trường trang trại.

Khi bạn tạo OpenIdRelyingParty, hãy đảm bảo bạn vượt qua null trong hàm tạo.

Điều này đặt trang web của bạn vào chế độ không trạng thái OpenID hoặc chế độ 'câm'. Nó hơi chậm cho người dùng đăng nhập (nếu bạn thậm chí còn nhận thấy) nhưng bạn tránh phải viết một IRelyingPartyApplicationStore để cho phép DotNetOpenAuth hoạt động trên trang trại của bạn;

var openIdRelyingParty = new OpenIdRelyingParty(null); 
+2

Tôi nghi ngờ điều này có thể giới thiệu lỗ hổng bảo mật tuy nhiên. Ai đó có thể xác nhận? –

4

Chúng tôi khắc phục vấn đề này bằng cách thực hiện IRelyingPartyApplicationStore (IOpenIdApplicationStore trong các phiên bản mới hơn của DotNetOpenAuth) và thêm tên cửa hàng đẳng cấp với .config

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

Giao diện là một thành phần của hai giao diện khác với năm tất cả các thành viên.

/// <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 
{ 
} 

Chúng tôi đã sử dụng chế độ câm để sửa lỗi nhanh chóng, nhưng cuối cùng bạn có thể muốn một cái gì đó như thế này.

5

Tất cả các cuộc thảo luận này xoay quanh những câu dưới đây:

như thế nào Relying Party (RP) đảm bảo các yêu cầu chứa token xác thực là đến từ các OP (OpenID Provider) mà ông đưa ra ý tưởng yêu cầu của người dùng?

bước sau giải thích làm thế nào nó sẽ xảy ra

  1. tài Yêu cầu nói đến Đảng trả lời (RP), website của chúng tôi trong trường hợp của chúng tôi
  2. cửa hàng ứng dụng một chữ ký duy nhất tương ứng với hồ sơ này vào một chữ ký tại địa phương lưu trữ (LSS) và sau đó nhúng chữ ký này vào Thư và chuyển tiếp Thư này tới Nhà cung cấp OpenId (OP)
  3. Người dùng nhập thông tin đăng nhập của mình và OP xác thực Thư của mình rồi chuyển tiếp Thư này có chữ ký vẫn được nhúng trong đó quay lại RP
  4. RP so sánh chữ ký đó được nhúng vào trong các tin nhắn để chữ ký mà là ở LSS và nếu chúng phù hợp RP xác thực người dùng

Nếu LSS biến mất (bằng cách nào đó) trước khi tin nhắn trở lại từ OP có không có gì cho RP để so sánh chữ ký với do đó nó không xác thực người dùng và ném lỗi: Chữ ký tin nhắn không chính xác.

thế nào có thể LSS Vanish:

  1. ASP.net làm mới hồ bơi ứng dụng
  2. IIS được khởi động lại
  3. Trong trang trại web nhắn được phục vụ bởi ứng dụng được lưu trữ trên máy chủ khác nhau

Hai giải pháp cho vấn đề này:

  1. Chạy RP ở chế độ câm

    a. Nó không lưu trữ và chữ ký tại địa phương và do đó không sử dụng so sánh chữ ký để đảm bảo Thư đến từ OP mà ông đã chuyển tiếp người dùng đến để xác thực

    b. Thay vào đó, một khi RP nhận được thông báo xác thực từ OP, nó sẽ gửi lại tin nhắn cho OP và yêu cầu anh ta kiểm tra xem anh ta là người đã xác thực người dùng này và là người khởi tạo tin nhắn. Nếu OP trả lời Có Tôi là người khởi tạo của Thông báo này và tôi đã tạo thông báo này thì người dùng được xác thực bằng RP

  2. Thực hiện lưu trữ lâu dài của riêng bạn mà không biến mất, không quan trọng những gì ASP.net thực hiện cho quá trình, giống như sử dụng SQL để lưu trữ trạng thái phiên.