10

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

誰にも回避策がありますか?

4

3 に答える 3

6

これは、Web ファーム環境で DotNetOpenAuth を使用する際の問題であることが判明しました。

OpenIdRelyingParty を作成するときは、コンストラクターに null を渡すようにしてください。

これにより、Web サイトが OpenID ステートレスまたは「ダム」モードになります。ユーザーがログインするのは少し遅くなりますが (気づいたとしても)、DotNetOpenAuth がファーム全体で機能するように IRelyingPartyApplicationStore を作成する必要はありません。

var openIdRelyingParty = new OpenIdRelyingParty(null);
于 2010-03-24T19:24:59.600 に答える
5

この議論はすべて、次の質問を中心に展開しています。

Relying Party (RP) は、認証トークンを含むリクエストが、ユーザーのリクエストを転送した OP (OpenId Provider) からのものであることをどのように確認しますか?

次の手順では、それがどのように発生するかを説明します

  1. ユーザーリクエストは、私たちの場合は私たちのウェブサイトである返信者(RP)に届きます
  2. アプリケーションは、このユーザーに対応する一意の署名をローカル署名ストア (LSS) に保存し、この署名をメッセージに埋め込み、このメッセージを OpenId プロバイダー (OP) に転送します。
  3. ユーザーが資格情報を入力すると、OP はメッセージを認証し、署名がまだ埋め込まれているこのメッセージを RP に転送します。
  4. RP は、メッセージに埋め込まれた署名を LSS にある署名と比較し、それらが一致する場合、RP はユーザーを認証します。

メッセージが OP から戻ってくる前に LSS が (何らかの形で) 消失した場合、RP が署名を比較するものがないため、ユーザーの認証に失敗し、エラーをスローします: メッセージの署名が正しくありませんでした。

LSS が消える方法:

  1. ASP.net はアプリケーション プールを更新します
  2. IIS が再起動されます
  3. Web ファームでは、メッセージは別のサーバーでホストされているアプリケーションによって提供されます

この問題に対する 2 つの解決策:

  1. RP はダム モードで実行されます

    を。ローカルに保存および署名しないため、署名比較を使用して、認証のためにユーザーを転送したOPからメッセージが送信されていることを確認しません

    b. 代わりに、RP が OP から認証メッセージを受信すると、メッセージを OP に送り返し、彼がこのユーザーを認証した人物であり、メッセージの発信者であるかどうかを確認するよう依頼します。OP が「私はこのメッセージの発信者であり、このメッセージを作成しました」と応答した場合、ユーザーは RP によって認証されます。

  2. SQL を使用してセッション状態を保存するのと同じように、ASP.net がプロセスに対して何をしても、消えない独自の永続ストアを実装します。

于 2010-09-30T09:28:35.623 に答える
4

IRelyingPartyApplicationStore(IOpenIdApplicationStore新しいバージョンの DotNetOpenAuth で) を実装し、ストア クラス名を .config に追加することで、この問題を修正しました。

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

このインターフェースは、5 つのメンバーを持つ他の 2 つのインターフェースをまとめたものです。

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

実行を開始するためのクイック フィックスとしてダム モードを使用しましたが、最終的には、おそらくこのようなものが必要になるでしょう。

于 2010-03-25T07:26:15.997 に答える