2017-06-02 6 views
2

認可コードフローの目的は、アクセストークンの認証コードを交換することです。この交換は、実際のアクセストークンがクライアントユーザーに公開されないように、ページを提供するサーバーと承認サーバーとの間で行われます。アクセストークンの保存方法? (Oauth 2、Auth code flow)

アクセストークンを取得したら、ページサーバーはそのトークンをどのように格納する必要がありますか?私はこのコードの一部が存在するPluralsightの例から学んでいた:これはクッキーに保存されたアクセストークンがある場合、各要求はチェックするようになります

public static HttpClient GetClient() 
    { 
     HttpClient client = new HttpClient(); 
     var accessToken = RequestAccessTokenAuthorizationCode(); 
     client.SetBearerToken(accessToken); 

     client.BaseAddress = new Uri(IdentityConstants.API); 
     client.DefaultRequestHeaders.Accept.Clear(); 
     client.DefaultRequestHeaders.Accept.Add(
      new MediaTypeWithQualityHeaderValue("application/json")); 

     return client; 
    } 

    private static string RequestAccessTokenAuthorizationCode() 
    { 
     // did we store the token before? 
     var cookie = HttpContext.Current.Request.Cookies.Get("ClientMVCCookie.AuthCode"); 
     if (cookie != null && cookie["access_token"] != null && !string.IsNullOrEmpty(cookie["access_token"])) 
     { 
      return cookie["access_token"]; 
     } 

     // no token found - request one 

     // we'll pass through the URI we want to return to as state 
     var state = HttpContext.Current.Request.Url.OriginalString; 

     var authorizeRequest = new IdentityModel.Client.AuthorizeRequest(
      IdentityConstants.AuthEndoint); 

     var url = authorizeRequest.CreateAuthorizeUrl(IdentityConstants.MVCClientSecret, "code", "management secret", 
      IdentityConstants.MVCAuthCodeCallback, state); 

     HttpContext.Current.Response.Redirect(url); 

     return null; 
    } 
} 

。そうでなければ、フローが開始される。コールバックは次のようになります。

public class CallbackController : Controller 
{ 
    // GET: STSCallback 
    public async Task<ActionResult> Index() 
    { 
     // get the authorization code from the query string 
     var authCode = Request.QueryString["code"]; 

     // with the auth code, we can request an access token. 
     var client = new TokenClient(
      IdentityConstants.TokenEndoint, 
      "mvc_client_auth_code", 
      IdentityConstants.MVCClientSecretAuthCode); 

     var tokenResponse = await client.RequestAuthorizationCodeAsync(
      authCode, 
      IdentityConstants.MVCAuthCodeCallback); 

     // we save the token in a cookie for use later on 
     var cookie = Response.Cookies["ClientMVCCookie.AuthCode"]; 
     cookie.Expires = DateTime.Now.AddMinutes(1); 
     cookie["access_token"] = tokenResponse.AccessToken; 

     // get the state (uri to return to) 
     var state = Request.QueryString["state"]; 

     // redirect to the URI saved in state 
     return Redirect(state); 
    } 
} 

アクセス許可トークンをCookieに格納しても、認証コードフロー全体の目的を逸脱しませんか。クッキーはクライアントブラウザに送信され、クライアントに公開されますか?何か不足していますか?これは、トークンを格納する正しい方法ではなく、どのように格納する必要がありますか?

答えて

3

クライアントはOAuthの用語で、リソースサーバーにリクエストを行うコンポーネントです。クライアントがWebアプリケーションのサーバー(ブラウザではありません)である場合、クライアントが要求します。

したがって、アクセストークンはWebアプリケーションサーバーにのみ保存する必要があります。ブラウザーはリソースサーバーへの直接の要求を決してしないので、ブラウザーに公開する必要はありません。代わりにWebアプリケーションサーバーと通信し、アクセストークンを使用してリソースサーバーに要求します。

ブラウザがWebアプリケーションサーバーで認証する方法は、OAuth 2.0とは関係ありません。たとえば、通常のセッションCookieであり、Webアプリケーションサーバーが各セッションまたは各ユーザーをアクセストークンに関連付ける場合があります。

アクセストークンの認証コードを交換するトークン要求はWebアプリケーションサーバーによって実行され、Webアプリケーションサーバーは認証サーバーで認証される必要があります(たとえば、共有client_secretを使用)。

認証コードフローは、クライアントが認証されることを保証し、正当なクライアントとして偽装された悪意のあるクライアントから保護します。すべてのWebアプリケーションクライアントにサーバーコンポーネントがあるわけではなく、場合によってはリソースサーバーへの要求がブラウザのJavaScriptコードによって直接行われます。このような状況では、ブラウザはクライアントであり、アクセストークンはブラウザ(JavaScript変数、ローカルストレージ、またはCookie内)に保存する必要があります。この場合、クライアントを認証することはできません(ただし、TLSと登録されたエンドポイントURLにのみサーバーをリダイレクトすることにより、合理的なセキュリティを実現できます)。 OAuth 2.0のセキュリティに関する

推奨読書:https://tools.ietf.org/html/rfc6819#section-4.3.3(RFC 6819)は

+0

私はその部分を完全に理解しています。私は質問に含まれている例が正しいかどうか尋ねていた。この例では、ASP.NET MVCサーバーでCookieを使用しています。私は、トークンを含むこのクッキーが、トークンを公開するブラウザに渡されると考えました(それは?)。 – BodzioSamolot

+0

このコードは説明なしに分析するのは難しいです。認証サーバーの一部ですか?クライアント? –

+0

これは、mvcサーバー側のアプリケーションです。コールバックコントローラは、アクセストークンの認証サーバーと認証コードを交換します。次に、トークンをクッキーに含めます。これは私が見つけた例です。トークンをブラウザに公開することはできません。これがなぜクッキーに保存されるのか私を甘やかす理由です。それは、それがブラウザへのその後の要求と共に移動することを意味しないのですか? – BodzioSamolot

0

クッキーはブラウザに公開されることはありません。これは、許可サーバーからクライアントに返される応答の一部です。クライアント自体はブラウザーではなくサーバーです。リダイレクトエンドポイントを実装するCallbackControllerは、応答からCookieを抽出します。

クッキーは決してブラウザに渡されません。クライアントのアプリケーションサーバーでブラウザがどのように認証されるかは、サンプルコードには表示されず、OAuthの一部でもありません。

承認サーバーは、トークンをCookieではなくリクエスト本体(JSON形式など)に格納することができます。しかし、これは違いはありません。なぜなら、クライアントは、とにかく応答全体を見て処理することができるからです。詳細について

、私の他の回答を参照してください。https://stackoverflow.com/a/44655679/2279059

サイドノート:CallbackControllerはにブラウザをリダイレクトするために、最終的なURLを保存するためにstateを使用しています。これは非標準ですが、機能します。ただし、実際にはstateはCSRF攻撃からリダイレクトエンドポイントを保護することを目的としています。 CallbackControllerstateを検証しませんが、与えられたURLにまったくリダイレ​​クトします。コードは例として意図されているので、おそらくこの詳細は除外されていました。しかし、このコードはおそらく完全に生産準備ができていないことを示しています。

+0

ありがとう;)それはまさに私が行方不明だったものです。クライアントは必ずしもクッキーをブラウザに渡すとは限りません。 – BodzioSamolot

関連する問題