0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OAuth & OIDC の認可コードフロー

Last updated at Posted at 2025-08-18

OAuth & OIDC の認可コードフロー

OAuth & OIDC の認可コードフローについて説明します。

特に重要なのが、confidential client, public client という概念です。confidential client は、シークレットを保持できるクライアントであり、public client はシークレットを保持できないクライアントです。

OAuth + confidential client

  • 背景
    • 日記アプリのバックエンドが、ユーザの Google カレンダー情報にアクセスしたい。
  • 登場人物
    • Authorization Server: Google 保有。Google カレンダーにアクセスするためのアクセストークンを発行する。
    • Resource server: Google 保有。Google カレンダーの情報を持っている。
    • Resource Owner: ユーザ
    • Client: 日記アプリのバックエンド
  • 詳細
    • 最終的に、アクセストークンは、日記アプリのバックエンドに配置される。
    • 日記アプリのバックエンドは、シークレットを保持することができるので、confidential client となります。
    • フローの最後に、日記アプリのバックエンドは、リダイレクトによって受け取った code と元々保持していた client secret を引っ提げて、Authorization Server にアクセストークンをもらいに行きます。client secret は攻撃者に知られていないはずなので、Authorization Server は client secret によって本物の日記アプリのバックエンドであることを検証できます。client secret の検証がないと、攻撃者に code を奪われたら、アクセストークンが取得されてしまいます。
    • OAuth は認可です。

OAuth + public client ※ PKCE を使います

  • 背景
    • 日記モバイルアプリのフロントエンドが、ユーザの Google カレンダー情報にアクセスしたい。
    • 日記モバイルアプリは、バックエンドを持たないものとする。
  • 登場人物
    • Authorization Server: Google 保有。Google カレンダーにアクセスするためのアクセストークンを発行する。
    • Resource server: Google 保有。Google カレンダーの情報を持っている。
    • Resource Owner: ユーザ
    • Client: 日記アプリのフロントエンド
  • 詳細
    • 最終的に、アクセストークンは、日記モバイルアプリのフロントエンドに配置される。
    • 日記モバイルアプリのフロントエンドは、シークレットを保持できないので、public client となります。
    • フローの最後に、日記モバイルアプリのフロントエンドは、リダイレクトによって受け取った code とフロー開始時に生成した code_verifier を引っ提げて、Authorization Server にアクセストークンをもらいに行きます。Authorization Server は code_verifier によって本物の日記モバイルアプリのフロントエンドであることを検証できます。code_verifier と code_challenge(code_verifier をハッシュ化したもの)は、認可フローの開始時に生成され、Client は手元に code_verifier を保持しておき、code_challenge は最初のリクエストに添えます。最後に、code とともに code_verifier を送ることで、Authorization Server は code_verifier と code_challenge と突き合わせて、本物の日記モバイルアプリのフロントエンドであることを検証できます。
    • code_verifier と code_challenge を使った仕組みが PKCE であり、一昔前は PKCE の仕組みがなく code のみの検証だったのですが、攻撃者に code を盗まれてアクセストークンを取得されてしまう事例が多発したため、PKCE が導入されました。
    • OAuth は認可です。

OIDC + public client ※ PKCE を使います

  • 背景
    • 日記アプリのフロントエンドが、日記アプリのバックエンドの認証を突破したい。
    • 認証に Google Login を使いたい。
  • 登場人物
    • Identity Provider: Google 保有。日記アプリのバックエンドの認証に使える ID トークンを発行する。
    • Relying Party: 日記アプリのフロントエンド
  • 詳細
    • 最終的に、IDトークンは、日記アプリのフロントエンドに配置される。
    • このフローは、日記アプリのバックエンドが Google を全面的に信頼していることで成り立ちます。
    • 認証フローの開始時に、scope=openid email profile をクエリパラメータに含めることで、Identity Provider(Google)に対してIDトークンにユーザーの基本情報、メールアドレス、プロフィール情報を含めることを要求します。
    • フローの最後に、日記アプリのフロントエンドは、リダイレクトによって受け取った code とフロー開始時に生成した code_verifier を引っ提げて、Identity Provider にIDトークンをもらいに行きます。これも PKCE の仕組みを使っています。
    • IDトークンの目的は、Google のリソースにアクセスすることではなく、日記アプリのバックエンドの認証を突破するためです。日記アプリのバックエンドは Google を信頼しているため、Google が発行したIDトークンを認証に使えます。
    • OIDC は認証です。

実装例: Cognito + Google ログインの詳細フロー

以下は、AWS Cognito を使った Google ログインの実際の実装フローです。

  1. ユーザーが Cognito Hosted UI にアクセス

    https://xxx.auth.ap-northeast-1.amazoncognito.com/oauth2/authorize?
    response_type=code&client_id=xxx&redirect_uri=http://localhost:8090/callback&
    scope=openid%20profile%20email&state=xxx&code_challenge_method=S256&
    code_challenge=xxx&identity_provider=Google
    
    • Cognito Hosted UI は認証画面(メールアドレス&パスワード入力欄、Google ボタン、Facebook ボタン)
    • code_challenge パラメータにより PKCE フローが開始
    • デスクトップアプリは localhost:8090 でサーバを起動して待機
    • identity_provider=Google が指定されているため、Cognito Hosted UI の認証画面が一瞬表示された後、即座に Google アカウント選択画面へリダイレクト
    • Cognito は code_challenge を保管
  2. Cognito から Google へリダイレクト

    https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?
    client_id=xxx&redirect_uri=https://xxx.auth.ap-northeast-1.amazoncognito.com/oauth2/idpresponse&
    scope=openid%20email%20profile&response_type=code&state=xxx
    
  3. Google でのユーザー認証

    • ユーザーが Google アカウントを選択
    • 初回ログイン時は同意画面が表示される
  4. Google から Cognito へ認可コード送信

    • Google がユーザー認証を完了し、認可コード(code)を発行
    • Cognito の /oauth2/idpresponse エンドポイントにリダイレクト
    • この code により、Cognito は Google のユーザー情報にアクセス可能
  5. Cognito でのユーザー検証

    • Cognito が Google から受け取った code を使って Google のトークンエンドポイントにアクセス
    • Google が Cognito に ID トークンを返却(ID トークン内に scope=openid email profile で要求されたユーザー情報が含まれる)
    • Cognito はユーザーが正当な Google アカウントを持つことを確認
  6. Cognito からデスクトップアプリへリダイレクト

    • Cognito が新しい認可コード(Google のものとは別)を発行
    • デスクトップアプリのコールバック URL にリダイレクト
    http://localhost:8090/callback?code=xxx&state=xxx
    
  7. デスクトップアプリでの認可コード受信

    • localhost:8090 で待機していたデスクトップアプリが認可コードを受信
  8. トークン取得

    • デスクトップアプリが認可コード + code_verifier を Cognito に直接 POST リクエスト
    POST https://xxx.auth.ap-northeast-1.amazoncognito.com/oauth2/token
    Content-Type: application/x-www-form-urlencoded
    
    [リクエストボディ]
    grant_type=authorization_code&client_id=xxx&code=xxx&
    redirect_uri=http://localhost:8090/callback&code_verifier=xxx
    
    • redirect_uri は認可リクエスト時と同じ値で検証用(リダイレクトのためではなく、OAuth 2.0 仕様による検証パラメータ)
    • code_verifier は PKCE による認証確認用
  9. ID トークン・アクセストークンの発行

    • Cognito が ID トークンとアクセストークンをデスクトップアプリに返却
    • デスクトップアプリは認証完了

このフローでは、Cognito が Google と デスクトップアプリの仲介役として機能し、純粋な OIDC 認証(openid email profile スコープ)を提供しています。

他のフロー

OAuth と言えば認可コードフローというイメージですが、一応他にもあります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?