2013-12-19 15 views
13

Asp.Net IDでFacebookのログイン用にredirect_uriを設定しようとしています。しかし、AccountControllerのGetExternalLogin RESTメソッドは、redirect_uriが '/'の場合にのみトリガされます。私がGetExternalLoginをトリガーしない何かを追加した場合、ブラウザは* error:invalid_request *だけを表示します。Asp.Net IDでredirect_uriを設定する

ただし、URLにはリダイレクトされたパラメータが含まれています。私はhttp://localhost:25432/testing

としてREDIRECT_URIを追加する場合、応答のURLは次のようになります。

http://localhost:25432/api/Account/ExternalLogin?provider=Facebook&response_type=token&client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A25432%2Ftesting&state=0NctHHGq_aiazEurHYbvJT8hDgl0GJ_GGSdFfq2z5SA1 

とブラウザウィンドウが表示さ: エラー:これは「にリダイレクトする場合にのみ機能する理由

INVALID_REQUEST任意のアイデアを/他のURLにはない?

ありがとうございます!

+0

我々がする必要があります「AccountController」の「ExternalLogin」アクションのコードを参照してください。リダイレクトが発生する場所です。 – trailmax

+0

@trailmax ASP.NET Projectダイアログでシングルページアプリケーションテンプレートを選択し、デモでreturn urlを変更した場合、実際に同じ問題が発生します。 '/'はjavascriptファイルの/ testingのようなものです。ありがとう! – doorman

答えて

4

app.UseOAuthBearerTokens(OAuthOptions)に使用されたOAuthOptions.AuthorizeEndpointPathとして登録されているのは、GetExternalLoginです。この構成では、エンドポイントの引数に検証が行われます。

if (!Uri.TryCreate(authorizeRequest.RedirectUri, UriKind.Absolute, out validatingUri)) 
{ 
    // The redirection endpoint URI MUST be an absolute URI 
} 
else if (!String.IsNullOrEmpty(validatingUri.Fragment)) 
{ 
    // The endpoint URI MUST NOT include a fragment component. 
} 
else if (!Options.AllowInsecureHttp && 
        String.Equals(validatingUri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase)) 
{ 
    // The redirection endpoint SHOULD require the use of TLS 
} 

そして、あなたはと 「エンドポイントの要求欠落している必要response_typeパラメータを許可」を渡す必要があり、この問題に遭遇するかもしれない他の誰のために

+0

ありがとう:)私は、ApplicationOAuthProvider.csファイル内のValidateClientRedirectUri関数でリダイレクトURLを設定しました。 – doorman

+0

これを回避し、** redirect_uri **を角度のあるhashbangのURLにする方法はありますか?例えば - **#/ register-external ** – WarrenDodsworth

23

「エンドポイントのリクエストを承認する、サポートされていないresponse_typeパラメータが含まれている」:ときに問題があります(コピー)のVisual Studio SPAのテンプレートからApplicationOAuthProvider.cs取ると、このコードがどこにあるか、それがあります:

public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) 
    { 
     if (context.ClientId == _publicClientId) 
     { 
      var expectedRootUri = new Uri(context.Request.Uri, "/"); 

      if (expectedRootUri.AbsoluteUri == context.RedirectUri) 
      { 
       context.Validated(); 
      } 
     } 

     return Task.FromResult<object>(null); 
    } 

は、これは明らかに任意のをブロックしますはhttp://localhost/http://domain.com/のようには見えないので、例えばhttp://domain.com/homeは動作しません。

今、下記これは、すべての作業を行い刀でInvokeAuthorizeEndpointAsyncのための源であり、あなたはそれがこのMVC /ウェブAPIアプリケーション(この登録は、通常Startup.Auth.csで起こる)のために登録される可能性があります任意のカスタムOAuthProviderに呼び出しを見ることができます。

private async Task<bool> InvokeAuthorizeEndpointAsync() 
    { 
     var authorizeRequest = new AuthorizeEndpointRequest(Request.Query); 

     var clientContext = new OAuthValidateClientRedirectUriContext(
      Context, 
      Options, 
      authorizeRequest.ClientId, 
      authorizeRequest.RedirectUri); 

     if (!String.IsNullOrEmpty(authorizeRequest.RedirectUri)) 
     { 
      bool acceptableUri = true; 
      Uri validatingUri; 
      if (!Uri.TryCreate(authorizeRequest.RedirectUri, UriKind.Absolute, out validatingUri)) 
      { 
       // The redirection endpoint URI MUST be an absolute URI 
       // http://tools.ietf.org/html/rfc6749#section-3.1.2 
       acceptableUri = false; 
      } 
      else if (!String.IsNullOrEmpty(validatingUri.Fragment)) 
      { 
       // The endpoint URI MUST NOT include a fragment component. 
       // http://tools.ietf.org/html/rfc6749#section-3.1.2 
       acceptableUri = false; 
      } 
      else if (!Options.AllowInsecureHttp && 
       String.Equals(validatingUri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase)) 
      { 
       // The redirection endpoint SHOULD require the use of TLS 
       // http://tools.ietf.org/html/rfc6749#section-3.1.2.1 
       acceptableUri = false; 
      } 
      if (!acceptableUri) 
      { 
       clientContext.SetError(Constants.Errors.InvalidRequest); 
       return await SendErrorRedirectAsync(clientContext, clientContext); 
      } 
     } 

     await Options.Provider.ValidateClientRedirectUri(clientContext); 

     if (!clientContext.IsValidated) 
     { 
      _logger.WriteVerbose("Unable to validate client information"); 
      return await SendErrorRedirectAsync(clientContext, clientContext); 
     } 

     var validatingContext = new OAuthValidateAuthorizeRequestContext(
      Context, 
      Options, 
      authorizeRequest, 
      clientContext); 

     if (string.IsNullOrEmpty(authorizeRequest.ResponseType)) 
     { 
      _logger.WriteVerbose("Authorize endpoint request missing required response_type parameter"); 
      validatingContext.SetError(Constants.Errors.InvalidRequest); 
     } 
     else if (!authorizeRequest.IsAuthorizationCodeGrantType && 
      !authorizeRequest.IsImplicitGrantType) 
     { 
      _logger.WriteVerbose("Authorize endpoint request contains unsupported response_type parameter"); 
      validatingContext.SetError(Constants.Errors.UnsupportedResponseType); 
     } 
     else 
     { 
      await Options.Provider.ValidateAuthorizeRequest(validatingContext); 
     } 

     if (!validatingContext.IsValidated) 
     { 
      // an invalid request is not processed further 
      return await SendErrorRedirectAsync(clientContext, validatingContext); 
     } 

     _clientContext = clientContext; 
     _authorizeEndpointRequest = authorizeRequest; 

     var authorizeEndpointContext = new OAuthAuthorizeEndpointContext(Context, Options); 

     await Options.Provider.AuthorizeEndpoint(authorizeEndpointContext); 

     return authorizeEndpointContext.IsRequestCompleted; 
    } 

これが鍵です:

 await Options.Provider.ValidateClientRedirectUri(clientContext); 

だからあなたのソリューションは、ValidateClientRedirectUriが検証を実行する方法を変更することです - デフォルトのSPAの実装があり、あなたのように非常に素朴な、見ることができます。

SPAに問題があるのは、主に有用な情報がなく、ASP.NET IdentityとOWINの両方について、KnockoutJSの実装で何が起こっているかという点です。

もう少し複雑なことをしようとする人は誰でも問題に遭遇するので、Microsoftはこれらのテンプレートに対してより包括的なドキュメントを提供したいと考えています。

これは、私のリダイレクトURIをブロックする上記の実装だと思ってOWIN(Katana)のソースコードを掘り下げていますが、うまくいけば他の人にも役立ちます。

HTH

+1

あなたがこのソリューションを投稿してから2年以上経っても、この投稿は依然としてトピックに関する最良の情報源です。 助けてくれてありがとう! – Cosmosis

+0

マイクロソフトは意図的にミドルウェアCRAPを学習する多くの開発者を浪費しています –

2

は、他の回答に基づいて、私はちょうどリダイレクトURIはそうのように同じドメイン上にあることを確認するためにApplicationOAuthProvider.csで検証コードを変更:

public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) 
     { 
      if (context.ClientId == _publicClientId) 
      { 
       Uri expectedRootUri = new Uri(context.Request.Uri, "/"); 

       if (context.RedirectUri.StartsWith(expectedRootUri.AbsoluteUri)) 
       { 
        context.Validated(); 
       } 
      } 

      return Task.FromResult<object>(null); 
     }