1. 序章

この記事では、OAuth 2.0、OpenID、およびKeycloakの簡単なレビューから始めます。 その後、Keycloak REST APIと、Postmanでそれらを呼び出す方法について学習します。

2. OAuth 2.0

OAuth 2.0 は、認証されたユーザーがトークンを介してサードパーティへのアクセスを許可できるようにする承認フレームワークです。 トークンは通常、有効期間が制限された一部のスコープに制限されます。 したがって、これはユーザーの資格情報の安全な代替手段です。

OAuth 2.0には、次の4つの主要コンポーネントが付属しています。

  • リソース所有者–保護されたリソースまたはデータを所有するエンドユーザーまたはシステム
  • リソースサーバー–サービスは、通常HTTPベースのAPIを介して保護されたリソースを公開します
  • クライアント–リソース所有者に代わって保護されたリソースを呼び出します
  • 承認サーバー– OAuth 2.0トークンを発行し、リソース所有者を認証した後、それをクライアントに配信します

OAuth 2.0は、いくつかの標準フローを備えたプロトコルですが、ここでは特に承認サーバーコンポーネントに関心があります。

3. OpenID C0nnect

OpenID Connect 1.0 (OIDC)は、OAuth 2.0の上に構築されており、プロトコルにID管理レイヤーを追加します。 したがって、クライアントはエンドユーザーのIDを確認し、標準のOAuth2.0フローを介して基本的なプロファイル情報にアクセスできます。 OIDCは、 openid profile email など、いくつかの標準スコープをOAuth2.0に導入しました。

4. 承認サーバーとしてのKeycloak

JBossは、JavaベースのオープンソースIDおよびアクセス管理ソリューションとしてKeycloakを開発しました。 OAuth 2.0とOIDCの両方のサポートに加えて、IDブローカリング、ユーザーフェデレーション、SSOなどの機能も提供します。

Keycloakは、管理コンソールまたはSpringアプリケーションに埋め込まれたスタンドアロンサーバーとして使用できます。 Keycloakをこれらのいずれかの方法で実行したら、エンドポイントを試すことができます。

5. Keycloakエンドポイント

Keycloakは、OAuth2.0フローのさまざまなRESTエンドポイントを公開します。

これらのエンドポイントをPostmanで使用するには、「Keycloak」という環境の作成から始めましょう。 次に、Keycloak認証サーバーのURL、レルム、OAuth 2.0クライアントID、およびクライアントパスワードのキー/値エントリをいくつか追加します。

次に、Keycloakテストを整理できるコレクションを作成しましょう。 これで、利用可能なエンドポイントを探索する準備が整いました。

5.1. OpenID構成エンドポイント

構成エンドポイントは、ルートディレクトリのようなものです。 他のすべての使用可能なエンドポイント、サポートされているスコープとクレーム、および署名アルゴリズムを返します。

Postmanでリクエストを作成しましょう: {{server}} / auth / realms /{{realm}}/。well-known/openid-configuration。Postmanは{{server}}の値を設定します実行時に選択した環境からのおよび{{realm}}

次に、リクエストを実行し、すべてがうまくいけば、次のような応答があります。

{
    "issuer": "http://localhost:8083/auth/realms/baeldung",
    "authorization_endpoint": "http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/auth",
    "token_endpoint": "http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/token",
    "token_introspection_endpoint": "http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/token/introspect",
    "userinfo_endpoint": "http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/userinfo",
    "end_session_endpoint": "http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/logout",
    "jwks_uri": "http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/certs",
    "check_session_iframe": "http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/login-status-iframe.html",
    "grant_types_supported": [...],
    ...
    "registration_endpoint": "http://localhost:8083/auth/realms/baeldung/clients-registrations/openid-connect",
    ...
    "introspection_endpoint": "http://localhost:8083/auth/realms/baeldung/protocol/openid-connect/token/introspect"
}

前述のように、応答で使用可能なすべてのエンドポイントを確認できます。たとえば、「 authentication_endpoint 」、「token_endpoint」などです。

さらに、応答には他にも有用な属性があります。 たとえば、サポートされているすべての付与タイプを「 grant_types_supported 」から、またはサポートされているすべてのスコープを「scopes_supported」から把握できます。

5.2. エンドポイントを承認する

OAuth2.0認証コードフローを担当する認証エンドポイントで旅を続けましょう。 これは、OpenID構成応答で「authorization_endpoint」として使用できます。

エンドポイントは次のとおりです。

{{サーバ}} / auth / realms / {{レルム}} / protocol / openid-connect / auth?response_type = code&client_id = jwtClient

さらに、このエンドポイントはscopeとredirect_uriをオプションのパラメーターとして受け入れます。

Postmanではこのエンドポイントを使用しません。 代わりに、通常、ブラウザを介して認証コードフローを開始します。 次に、アクティブなログインCookieが利用できない場合、Keycloakはユーザーをログインページにリダイレクトします。 最後に、認証コードがリダイレクトURLに配信されます。

次のステップに進んで、アクセストークンを取得する方法を確認しましょう。

5.3. トークンエンドポイント

トークンエンドポイントを使用すると、アクセストークン、更新トークン、またはIDトークンを取得できます。 OAuth 2.0は、次のようなさまざまな付与タイプをサポートします authentication_code refresh_token、 またパスワード。

トークンエンドポイントは次のとおりです。{{server}} / auth / realms / {{realm}} / protocol / openid-connect / token

ただし、各付与タイプには、専用のフォームパラメータが必要です。

まず、トークンエンドポイントをテストして、認証コードのアクセストークンを取得しましょう。 次のフォームパラメータをリクエスト本文に渡す必要があります: client_id client_secret grant_type code redirect_uri [ X159X]。 トークンエンドポイントは、オプションのパラメーターとしてscopeも受け入れます。

さらに、認証コードフローをバイパスする場合は、 パスワード付与タイプが選択ですここではユーザーの資格情報が必要なので、Webサイトまたはアプリケーションに組み込みのログインページがある場合にこのフローを使用できます。

Postmanリクエストを作成し、フォームパラメータ client_id client_secret grant_type username 、およびpasswordを渡します。体内:

このリクエストを実行する前に、username変数とpassword変数をPostmanの環境キー/値ペアに追加する必要があります。

もう1つの便利な付与タイプは、refresh_tokenです。 これは、トークンエンドポイントへの前回の呼び出しからの有効な更新トークンがある場合に使用できます。 トークンの更新フローには、パラメーター client_id client_secret grant_type 、およびrefresh_tokenが必要です。

他のエンドポイントをテストするには、応答access_tokenが必要です。 Postmanでのテストを高速化するために、トークンエンドポイントリクエストのTestsセクションにスクリプトを記述できます。

var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("refresh_token", jsonData.refresh_token);
postman.setEnvironmentVariable("access_token", jsonData.access_token);

5.4. ユーザー情報エンドポイント

有効なアクセストークンがある場合、ユーザー情報エンドポイントからユーザープロファイルデータを取得できます。

ユーザー情報エンドポイントは、 {{server}} / auth / realms / {{realm}} / protocol / openid-connect/userinfoで入手できます。

それに対するPostmanリクエストを作成し、Authorizationヘッダーでアクセストークンを渡します。

次に、リクエストを実行します。 成功した応答は次のとおりです。

{
    "sub": "a5461470-33eb-4b2d-82d4-b0484e96ad7f",
    "preferred_username": "[email protected]",
    "DOB": "1984-07-01",
    "organization": "baeldung"
}

5.5. トークンイントロスペクトエンドポイント

リソースサーバーがアクセストークンがアクティブであることを確認する必要がある場合、またはアクセストークンに関するメタデータをさらに必要とする場合、特に不透明なアクセストークンの場合、トークンイントロスペクトエンドポイントがその答えです。 この場合、リソースサーバーはイントロスペクトプロセスをセキュリティ構成と統合します。

Keycloakのイントロスペクトエンドポイントを次のように呼び出します: {{server}} / auth / realms / {{realm}} / protocol / openid-connect / token / introspect

Postmanでイントロスペクトリクエストを作成し、 client_id client_secret 、およびtokenをフォームパラメーターとして渡します。

access_token が有効な場合、次の応答があります。

{
    "exp": 1601824811,
    "iat": 1601824511,
    "jti": "d5a4831d-7236-4686-a17b-784cd8b5805d",
    "iss": "http://localhost:8083/auth/realms/baeldung",
    "sub": "a5461470-33eb-4b2d-82d4-b0484e96ad7f",
    "typ": "Bearer",
    "azp": "jwtClient",
    "session_state": "96030af2-1e48-4243-ba0b-dd4980c6e8fd",
    "preferred_username": "[email protected]",
    "email_verified": false,
    "acr": "1",
    "scope": "profile email read",
    "DOB": "1984-07-01",
    "organization": "baeldung",
    "client_id": "jwtClient",
    "username": "[email protected]",
    "active": true
}

ただし、無効なアクセストークンを使用すると、応答は次のようになります。

{
    "active": false
}

6. 結論

この記事では、Keycloakサーバーを実行して、承認、トークン、ユーザー情報、およびイントロスペクトエンドポイントに対するPostmanリクエストを作成しました。

Postmanリクエストの完全な例は、GitHubでいつものように利用できます。