ここまで準備したサンプルアプリケーションの構成は、以下の図1のようになっています。なお、図中内の「Authorizationエンドポイント」および「Tokenエンドポイント」は、OAuth/OIDCで規定されている“アクセストークンを発行するためのURL”を表します。
以下に図1の動作の流れを説明します。
(1)リダイレクト:customer-app(またはproduct-app)の保護されたURLにアクセスすると、KeycloakのAuthorizationエンドポイント(ログイン画面)へリダイレクトされる。
(2)ログイン:エンドユーザーはKeycloakに対してユーザー名、パスワードを送信してログインを行う。
(3)Webアクセス:Keycloakでのログインが成功すると、URLパラメータの情報を基にしてリダイレクト元であるcustomer-appの画面に戻る。この際に認可コードと呼ばれる文字列がURLパラメータとしてKeycloakからアプリケーションに渡される。
(4)アクセストークン発行:customer-appは認可コードとアプリケーションの情報をKeycloakのTokenエンドポイントに送信する。Keycloakは認可コードとアプリケーションの情報からcustomer-appを認証し、アクセストークンを発行する。
(5)トークン付きHTTPアクセス:customer-appはアクセストークンを利用してdatabase-serviceにリクエストを送信する。database-serviceはアクセストークンを基にユーザー、アプリケーションを認証し、リクエストに対するレスポンスを返す。
上記の動作から、エンドユーザーの認証情報(ユーザー名やパスワード)は各アプリケーションに送信されず、アクセストークンによってアプリケーション間の認可情報の受け渡しが行われます。
この流れで重要になる「(A)KeycloakのAuthorizationエンドポイントからのログイン」「(B)KeycloakのTokenエンドポイントからトークンを取得」「(C)Authorizationヘッダにアクセストークンを付けたリクエスト送信」を、WebブラウザおよびRESTクライアントを利用して確認していきます。
まずは、Webブラウザから動作を確認するため、「http://localhost:8080/customer-portal」にアクセスします(画面4)。
customer-portalでは「/customer-portal/customers/*」および「/customer-portal/admin/*」のパスに対して、Keycloakクライアントアダプターによるアクセス制限がかかっています。この制限されたパスにアクセスするため「Customer Listing」をクリックして、「/customer-portal/customers/view.jsp」にアクセスします。すると、Keycloakクライアントアダプターによって、KeycloakのAuthorizationエンドポイントにリダイレクトされ、Webブラウザにログイン画面が表示されます(画面5)。
このとき、AuthorizationエンドポイントのURLとパラメータは以下のようになっています。
http://localhost:8080/auth/realms/demo/protocol/openid-connect/auth?
response_type=code&
client_id=customer-portal&
redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcustomer-portal%2Fcustomers%2Fview.jsp&
state=c222141a-876c-4079-ac3c-d145be19583c&
login=true&
scope=openid
そして、(A)KeycloakのAuthorizationエンドポイントからログインを行います。ログインに利用するユーザーは「testrealm.json」をインポートした際に作成されているので、そのユーザーでアクセスします。今回は「admin/password」でログインします。ログインが成功すると、以下のURLにリダイレクトされます。
http://localhost:8080/customer-portal/customers/view.jsp?
state=c222141a-876c-4079-ac3c-d145be19583c&
code=YOc4ndRVuapTliDad6JAnZk4V5n7ZnnLWaX86Y_Mfeo.cd5d91a1-dcc9-49b0-9e6a-2c0d9115def1
このリダイレクトされた際のcodeを利用して、アプリケーションが(B)Tokenエンドポイントからアクセストークン、IDトークンを取得します。アプリケーションのコード中にアクセストークンを取得する処理は記載されていませんが、これはKeycloakのクライアントアダプターが処理を行っているためです。
そして、customer-appはdatabase-serviceに対し、(C)Authorizationヘッダにアクセストークンを付けたリクエストを送信して、データを取得します。database-serviceはアクセストークンに含まれる認可情報を確認し、customer-appにレスポンスを返します。customer-appではこのレスポンスの内容がWebブラウザに表示されます(画面6)。
また、Keycloakのクライアントアダプターは、Cookieによる認可情報の確認にも対応しているため、customer-appにログインした状態でproduct-portal「http://localhost:8080/product-portal/products/view.jsp」にアクセスすると、エンドユーザーはログインすることなくアクセスすることができるようになります。
さらに、Keycloakとクライアントアダプターの間で行われている処理の詳細を確認するため、RESTクライアントを利用して(B)および(C)の動作を確認してみます。
RESTクライアントを利用して確認する前に、Keycloak上でcustomer-appの設定を変更します。Keycloakにログイン後、「Clients」→「customer-portal」を選択し、customer-portalの「Direct Access Grants Enabled」という項目を「ON」にします(画面7)。この設定の詳細に関しては省きますが、RESTクライアントによる確認を簡略化するために設定します。
設定後は、適当なRESTクライアントを用いてアクセストークンを発行します。アクセストークンを発行するために、Tokenエンドポイント(http://localhost:8080/auth/realms/demo/protocol/openid-connect/token)に以下のパラメータをPOSTします。
パラメータ名 | 値 | |
---|---|---|
Header | Content-Type | application/x-www-form-urlencoded |
Body | grant_type | password |
client_id | customer-portal | |
client_secret | password | |
username | admin | |
password | password | |
リクエストが成功すると、以下の画面8のようなアクセストークンが取得できます。
これで、(B)KeycloakのTokenエンドポイントからトークンを取得することができました。
次に、このアクセストークンを使ってdatabase-serviceから値を取得します。アクセストークンは「Bearerスキーム」という形式で、HTTPのAuthorizationヘッダに指定します。
Authorization: Bearer <アクセストークン>
上記のヘッダを付けて、database-serviceのエンドポイント「http://localhost:8080/database/customers」や「http://localhost:8080/database/products」にリクエストを送信すると、以下の画面9のようなレスポンスが得られます。
これで(C)Authorizationヘッダにアクセストークンを付けたリクエスト送信が確認できました。
最後に、ここで取得したアクセストークン、IDトークンの中身を確認してみましょう。
Keycloakから取得したアクセストークン、IDトークンは「Json Web Token(JWT)」というフォーマットを利用しています。JWTは下記のように、Base64エンコードしたHeader、Payload、 Signatureを「.」(ピリオド)で結合した形式になっています。
Base64(Header).Base64(Payload).Base64(Signature)
しかし、ここままでは内容を確認することができないので、「http://jwt.io」を利用してID Tokenの中身を表示してみます。jwt.ioではJWTの内容を確認するためのWebアプリケーションが提供されています。このアプリケーションにKeycloakから取得したアクセストークン、IDトークンを入力すると、デコードされた内容が表示されます(画面10)。
このように、ID Tokenには認証されたユーザー名やトークンを発行したサーバ名といった情報が記載されていることが分かります。また、今回は詳細の説明を省きますが、Keycloakが提供する公開鍵とSignatureを利用することで、このトークンが改ざんされていないことを検証でき、検証が成功した場合にこれらの情報が正しいものであることを信頼することができます。
次回はKeycloakのクライアントアダプターを利用し、実際にアプリケーションを構築してみます。
株式会社日立製作所 OSSソリューションセンタ所属。これまではソフトウェアエンジニアとしてストレージやサーバの管理ソフトウェア開発に従事してきた。現在は、主にアイデンティティー管理OSSやAPI管理OSSの検証、導入支援を行っている。
Copyright © ITmedia, Inc. All Rights Reserved.