🔖

DrupalのSimple OAuthとPostmanを使ったOAuth認証の確認

2024/03/02に公開

概要

DrupalのSimple OAuthとPostmanを使ったOAuth認証の確認を行います。

以前に以下の記事を書きましたが、もう少し掘り下げてみます。

https://zenn.dev/nakamura196/articles/e4ce978db12227

DrupalでSimple OAuthの設定を行う

以下を参考にしてください。

https://zenn.dev/nakamura196/articles/e4ce978db12227#oauthクライアントの作成

Postman

グラントタイプがpasswordの場合

/oauth/token に対して、Body > x-www-form-urlencoded に以下を指定しました。

キー
grant_type password
client_id {作成したCLIENT_ID。例:gt8UKlKltI4qs1XP5KLucIXiYw9ulGb0xS4RyO437dc}
client_secret {作成したCLIENT_SECRET。例:test}
username {ユーザ名。例:yamato}
password {パスワード。例:yamato}

結果、以下のようなJSONが返却されました。

{
    "token_type": "Bearer",
    "expires_in": 300,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJS...",
    "refresh_token": "def50200295e412f..."
}

jwt.ioで確認したところ、以下のようにデコードされました。

{
  "aud": "gt8UKlK...",
  "jti": "6dc1fee..",
  "iat": 1709386974,
  "nbf": 1709386974,
  "exp": 1709387274.122002,
  "sub": "2",
  "scope": [
    "authenticated",
    "cj"
  ]
}

subはDrupalのユーザのIDに該当し、scopeはDrupalで設定した値が返却されました。

異なるユーザでログインした場合、異なるsubが与えられました。

ユーザ名またはパスワードをまちがえる

以下が返却されました。

{
    "error": "invalid_grant",
    "error_description": "The user credentials were incorrect.",
    "message": "The user credentials were incorrect."
}

間違ったscopeを指定する

以下のように、間違ったscopeを指定します。

キー
grant_type password
client_id {作成したCLIENT_ID。例:gt8UKlKltI4qs1XP5KLucIXiYw9ulGb0xS4RyO437dc}
client_secret {作成したCLIENT_SECRET。例:test}
username {ユーザ名。例:yamato}
password {パスワード。例:yamato}
scope test

以下が返却されました。

{
    "error": "invalid_scope",
    "error_description": "The requested scope is invalid, unknown, or malformed",
    "hint": "Check the `test` scope",
    "message": "The requested scope is invalid, unknown, or malformed"
}

グラントタイプrefresh_tokenを使用する

グラントタイプrefresh_tokenを使用する場合、usernamepasswordは不要で、refresh_tokenを指定する必要がありました。

キー
grant_type refresh_token
client_id {作成したCLIENT_ID。例:gt8UKlKltI4qs1XP5KLucIXiYw9ulGb0xS4RyO437dc}
client_secret {作成したCLIENT_SECRET。例:test}
refresh_token def50200a7d875010a068813927613be306944301b05358dd2dff39758cba3faa94ab2e6603c6a2e5a58d0262967f19fc6936ea764057f018df087c42fb5bcc0166db225efa7ce351dd6c82b64765350d6297e80e1118e9da7e004d2e17294d2b213b9d9c08ff16b29e6a59ffade5584e9aba4d2bda91b57cb7538c62b79520f...

結果、以下のようなJSONが返却されました。

{
    "token_type": "Bearer",
    "expires_in": 300,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJS...",
    "refresh_token": "def50200295e412f..."
}

グラントタイプclient_credentialsを使用する

以下のように、グラントタイプにclient_credentialsを指定してみました。

キー
grant_type client_credentials
client_id {作成したCLIENT_ID。例:gt8UKlKltI4qs1XP5KLucIXiYw9ulGb0xS4RyO437dc}
client_secret {作成したCLIENT_SECRET。例:test}
username {ユーザ名。例:yamato}
password {パスワード。例:yamato}

結果、以下のように、access_tokenのみを含むjsonが返却されました。

{
    "token_type": "Bearer",
    "expires_in": 300,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjIxZjYxOThlMWIxNTI0ZGM1NTcxZjJiZDM3N2M4NWI2N2IzYTE1NDU5MWVjZTUwN2QzNDEwNjBkYmVhNDEyOTg5MjI5NDAzYjFkOTFlODBmIn0.eyJhdWQiOiJndDhVS2xLbHR..."
}

グラントタイプpasswordと比較して、refresh_tokenが含まれていませんでした。

ChatGPT 4に聞く

grant_typeの種類

grant_typeに指定する具体的な文字列は、OAuth 2.0仕様で定義されている値を使用します。以下は、主なgrant_typeの値とその用途です:

  1. Authorization Code Grant

    • 文字列: authorization_code
    • 用途: サーバーサイドWebアプリケーションで使用され、クライアントがリダイレクトを通じてユーザーのブラウザから認可コードを受け取り、そのコードを使ってアクセストークンを取得します。
  2. Implicit Grant

    • 文字列: implicit
    • 用途: ブラウザベースのアプリケーション(例:シングルページアプリケーション)で使用されますが、セキュリティ上の理由からOAuth 2.0では推奨されず、OAuth 2.1では削除される予定です。
  3. Resource Owner Password Credentials Grant

    • 文字列: password
    • 用途: ユーザーが信頼できるアプリケーションに直接ユーザーネームとパスワードを提供する場合に使用しますが、セキュリティ上の理由から推奨されません。
  4. Client Credentials Grant

    • 文字列: client_credentials
    • 用途: アプリケーション自身の認証に使用され、主にアプリケーション間のAPIアクセスで利用されます。
  5. Refresh Token Grant

    • 文字列: refresh_token
    • 用途: 既に取得したアクセストークンが失効した場合に、新しいアクセストークンを取得するために使用します。

これらの値は、OAuthトークンエンドポイントへのリクエストでgrant_typeパラメータとして指定されます。適切なgrant_typeを選択することで、アプリケーションはOAuthサーバーと安全に通信し、必要な認証フローを実施できます。

passwordグラントタイプとclient_credentialsグラントタイプの違い

passwordグラントタイプとclient_credentialsグラントタイプは、OAuth 2.0で定義されている異なる認証フローを表しており、それぞれ異なるユースケースとセキュリティ要件に対応しています。ここでは、それぞれの違いについて説明します。

Password Grant

  • グラントタイプ: password
  • 用途: このフローは、ユーザーがクライアントアプリケーションに直接自分のユーザー名とパスワードを提供できる信頼できるアプリケーションで使用されます。ユーザーがアプリケーションを信頼している場合に限り、この方法でユーザーの認証情報をアプリケーションに渡すことができます。
  • セキュリティ: ユーザー名とパスワードを直接アプリケーションに渡すため、セキュリティリスクが高いとされ、一般的には推奨されません。特に、ユーザー認証情報の扱いには細心の注意が必要です。

Client Credentials Grant

  • グラントタイプ: client_credentials
  • 用途: このフローは、アプリケーション自身が認証される場合に使用されます。つまり、ユーザーの代わりにアクセスするのではなく、アプリケーションが自身の資格情報(クライアントIDとクライアントシークレット)を使用して認証を行い、APIやリソースへのアクセスを得るために使用します。
  • セキュリティ: このフローは、アプリケーション間の認証に限定され、ユーザー認証情報を扱わないため、passwordグラントタイプに比べてセキュリティリスクが低いとされます。アプリケーションは自身の資格情報を保持し、それを用いて認証を行います。

主な違い

  • 認証対象: passwordはユーザーの認証情報を使用し、client_credentialsはアプリケーションの認証情報を使用します。
  • 使用場面: passwordは特定の信頼できるクライアントアプリケーションに限定され、client_credentialsはアプリケーション間の認証に適しています。
  • セキュリティ: passwordはユーザー認証情報を直接扱うため、セキュリティ上の懸念がありますが、client_credentialsはアプリケーション自身の認証に限られるため、リスクが低いです。

適切なグラントタイプの選択は、アプリケーションのユースケース、セキュリティ要件、そしてユーザーとの信頼関係に基づいて行うべきです。

Nuxt 3で作成されたフロントエンドアプリケーションと、Drupalで構築されたバックエンド兼OAuthクライアントを例にすると?

Nuxt 3で作成されたフロントエンドアプリケーションと、Drupalで構築されたバックエンド兼OAuthクライアントを例にとって、passwordグラントタイプとclient_credentialsグラントタイプを使った認証フローを説明します。

1. Password Grantフロー

このシナリオでは、ユーザーは直接Nuxt 3フロントエンドアプリケーションに認証情報(ユーザー名とパスワード)を提供します。その後、フロントエンドアプリケーションはこの情報を使用してDrupalバックエンドからトークンを取得します。

  1. ユーザー認証: ユーザーがNuxt 3アプリケーションにログイン情報(ユーザー名とパスワード)を入力します。
  2. トークンリクエスト: Nuxt 3アプリケーションは、ユーザーから受け取った認証情報をgrant_type=passwordと共にDrupalバックエンドのOAuthエンドポイントにPOSTリクエストとして送信します。
  3. トークンの発行: Drupalバックエンドはユーザーの認証情報を検証し、認証が成功するとアクセストークン(およびオプションでリフレッシュトークン)をNuxt 3アプリケーションに返します。
  4. アクセストークンの使用: Nuxt 3アプリケーションはこのアクセストークンを使用して、ユーザーの代わりにDrupalバックエンドの保護されたリソースへアクセスします。

2. Client Credentials Grantフロー

このシナリオでは、Nuxt 3アプリケーション自体がDrupalバックエンドに対して認証され、ユーザーではなくアプリケーション自身のためにリソースへのアクセスを要求します。

  1. アプリケーション認証: Nuxt 3アプリケーションは、自身のクライアントIDとクライアントシークレットを使用してDrupalバックエンドのOAuthエンドポイントにgrant_type=client_credentialsと共にPOSTリクエストを送信します。
  2. トークンの発行: Drupalバックエンドはアプリケーションの認証情報を検証し、認証が成功するとアクセストークンをNuxt 3アプリケーションに返します。
  3. アクセストークンの使用: Nuxt 3アプリケーションはこのアクセストークンを使用して、アプリケーション自身のためにDrupalバックエンドの保護されたリソースへアクセスします。

選択基準

  • Password Grantは、ユーザーがフロントエンドアプリケーションに直接ログインする必要がある場合に適しています。しかし、ユーザーの認証情報を直接扱うため、セキュリティに注意が必要です。
  • Client Credentials Grantは、アプリケーションが自身のためにAPIを利用するシナリオ、例えばバックグラウンドでデータを同期する場合などに適しています。ユーザーの介在しない認証フローであり、アプリケーシ..

リフレッシュトークンの扱い

Nuxt3で作成したフロントエンドとDrupalで構築されたバックエンドを持つアプリケーションで、passwordグラントタイプとclient_credentialsグラントタイプを使用したOAuth認証のフローについて説明します。このコンテキストでは、DrupalがOAuthクライアントの役割を果たし、フロントエンド(Nuxt3アプリ)からのリクエストを受けて、バックエンドである自身または別のサービスに対して認証を行います。

passwordグラントタイプの場合

  1. ユーザー認証: Nuxt3アプリのユーザーがログインフォームにユーザー名とパスワードを入力します。
  2. トークンリクエスト: Drupalバックエンドは、ユーザーから受け取った認証情報とpasswordグラントタイプを使用して、OAuthサーバーにトークンをリクエストします。
  3. トークン応答: OAuthサーバーは、リクエストを検証し、認証情報が正しい場合はアクセストークンとリフレッシュトークンをDrupalに返します。
  4. アクセス&リフレッシュ: Drupalバックエンドはアクセストークンを使用して保護されたリソースへアクセスし、リフレッシュトークンを使用してアクセストークンが期限切れになった場合に新しいトークンを取得します。

client_credentialsグラントタイプの場合

  1. アプリケーション認証: Drupalバックエンドが自身のクライアントIDとクライアントシークレットを使用して、OAuthサーバーに対してclient_credentialsグラントタイプでトークンリクエストを行います。
  2. トークン応答: OAuthサーバーはリクエストを検証し、クレデンシャルが正しい場合はアクセストークンのみをDrupalに返します。このケースではリフレッシュトークンは返されません。
  3. アプリケーション間のアクセス: Drupalバックエンドは取得したアクセストークンを使用して、他の保護されたリソースやAPIへのアクセスを行います。

リフレッシュトークンの扱い

  • passwordグラントタイプ: ユーザー認証に基づき、アクセストークンとともにリフレッシュトークンも発行されます。リフレッシュトークンはアクセストークンが失効した場合に新しいアクセストークンを取得するために使用されます。
  • client_credentialsグラントタイプ: アプリケーション自身の認証に基づくため、リフレッシュトークンは通常発行されません。アクセストークンが失効した場合、アプリケーションは再度クライアントクレデンシャルを使用して新しいアクセストークンをリクエストする必要があります。

この違いは、passwordグラントタイプがエンドユーザーの認証情報を扱うため、ユーザーのセッション管理にリフレッシュトークンが有用であるのに対し、client_credentialsグラントタイプはアプリケーション自体の認証であり、セッション管理が不要なシナリオで使用されるためです。

まとめ

OAuthで使用するグラントタイプの違いや、それに伴うrefresh_tokenの取り扱いの違いなどが少しずつわかってきました。

色々と誤っている点もあるかもしれませんが、参考になりましたら幸いです。

Discussion