3

OAuth コントローラーに Authorize メソッド用のカスタム認証フィルターがあります。認可フィルターは、ユーザーがログインしていることを認識すると、現在の OAuth 要求をセッションに詰め込み、ログインのために送信します。

ログイン後、 /OAuth/Authorize エンドポイントで、現在のリクエストに承認リクエストが添付されていないためにすぐに失敗するのではなく、そのリクエストがセッション内にあるかどうかを確認します。次に、そのリクエスト オブジェクトで認可サーバーを呼び出します。

Authorize アクションのコードは次のようになります。

    [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
    [ExternalAppAuthorizeAttribute]
    public ActionResult Authorize() {
        Object requestObject = this.HttpContext.Session["AuthRequest"];
        HttpRequestBase request = null;
        if ((requestObject != null) && (requestObject.GetType() == typeof(HttpRequestWrapper)))
        {
            request = (HttpRequestWrapper)requestObject;
            this.HttpContext.Session.Remove("AuthRequest");
        }
        EndUserAuthorizationRequest pendingRequest = null;
        if (request != null)
        {
            pendingRequest = this.authorizationServer.ReadAuthorizationRequest(request);
        } else
        {
            pendingRequest = this.authorizationServer.ReadAuthorizationRequest();
        }
        if (pendingRequest == null) {
            throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
        }

ただし、ReadAuthorizationRequest は、セッションで要求が検出されて復元されたときに失敗します。エラー メッセージはあまり役に立ちません。「値が期待される範囲内にありません。」

スタックトレースは次のとおりです。

[ArgumentException: Value does not fall within the expected range.]
   System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) +0
   System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode) +10
   System.Web.Util.Misc.ThrowIfFailedHr(Int32 hresult) +9
   System.Web.Hosting.IIS7WorkerRequest.GetServerVariableInternal(String name) +36
   System.Web.Hosting.IIS7WorkerRequest.GetServerVariable(String name) +49
   System.Web.HttpRequest.AddServerVariableToCollection(String name) +22
   System.Web.HttpRequest.FillInServerVariablesCollection() +85
   System.Web.HttpServerVarsCollection.Populate() +36
   System.Web.HttpServerVarsCollection.Get(String name) +42
   System.Collections.Specialized.NameValueCollection.get_Item(String name) +10
   DotNetOpenAuth.Messaging.MessagingUtilities.GetPublicFacingUrl(HttpRequestBase request, NameValueCollection serverVariables) +61
   DotNetOpenAuth.Messaging.MessagingUtilities.GetPublicFacingUrl(HttpRequestBase request) +43
   DotNetOpenAuth.Messaging.Channel.ReadFromRequestCore(HttpRequestBase request) +69

飛行中のリクエストを調べたところ、ヘッダー、URI など、 oauthで使用されているものはすべて問題ないように見えます。何が原因なのか途方に暮れています。

なぜこれが当てはまるのか誰にもわかりますか?または、ユーザーの認証中に oauth リクエストを保存するための別の推奨事項がある場合は、私はそれらを受け入れます。

4

1 に答える 1

4

HttpRequestWrapper の ServerVariables が呼び出されたときに例外をスローしていたことが判明しました (これはスタック トレースから明らかです)。これは、リクエストがフィルターによって傍受されて以来、コントローラーのアクションにまだヒットしていないためだと思います。リクエストがコントローラーアクションによって処理されるときに ServerVariables が設定されると思いますか?

HttpRequestBase を実装する新しいクラスを作成することで、これを解決しました。保存した oauth リクエストと実際のリクエストを渡し、現在のリクエストから返された ServerVariables を除く HttpRequestBase 内のすべてのプロパティを oauth リクエストから返しました。

于 2013-04-25T18:31:51.423 に答える