Keycloakで認可サービスを試してみよう[後編]:Keycloak超入門(最終回)(2/3 ページ)
本連載では、近年注目されている認証プロトコル「OpenID Connect」をサポートするオープンソースのシングルサインオン(SSO)ソフトウェア「Keycloak」の活用方法を解説していきます。Keycloakの認可サービスを利用することで、アプリケーションに対して、より細やかで柔軟なアクセス制御を実現することが可能です。今回は、後編をお届けします。
設定と実装の確認
一通りの動作確認を終え、UMA方式の挙動を理解できたでしょうか?
以降では、UMA方式を動かすに当たっての各アクターの主要な設定を確認していきます。設定の解説に先立って、各アクターで必要となる設定や実装の概要をあらためて記載しておきます。
・Keycloak(認可サーバ)
   UMA機能の有効化
   リソースサーバのクライアントの設定(認可の有効化)
   リソースサーバ上のリソースに対し、リソースオーナーからのアクセス
   だけを許可する認可設定
・Webアプリ(クライアント)
   Webアプリのアダプター(JavaScriptアダプター)の設定
   RPTを取得/パーミッション申請の実装方法
・APIサービス(リソースサーバ)
   APIサービスのアダプター(Tomcatアダプター)の設定
   Keycloakへリソース情報を登録/削除する際の実装方法
Keycloak(認可サーバ)の設定
●レルムの設定
まずは、Keycloak管理コンソール(http://sso.example.com/auth/admin/)にアクセスし、Keycloak管理者(admin)でログインして、「Demo-authz」レルムの「レルムの設定」を確認します(画面16)。UMA方式を利用するためには、「User-Managed Access」が「オン」になっている必要があります。
●UMA方式に関連するクライアント設定
「Demo-authz」レルムの「クライアント」には、後述するクライアントアダプターの設定と対応する「authz-uma-api」(リソースサーバ)と「authz-uma-client」(クライアント)の2つのクライアントを登録しておく必要があります。ここでは、UMA方式を利用する上で特徴的な設定が必要な「authz-uma-api」のクライアント設定についてのみ解説します。
「Demo-authz」レルムの「クライアント」から「authz-uma-api」を選択し、以下の表4〜7の設定意図を確認します。UMAのリソースサーバはOAuthのクライアントでもあるため、Keycloakにはクライアントとして登録します。UMAのリソースサーバが他のOAuthのクライアントと異なるのは、スコープ「uma_protection」を必要とすることです。表4の「認可の有効」をオンにすると、「uma_protection」ロールが付与されてProtection APIを利用できるようになります。また、設定ページのタブが増えてきめ細かな認可の制御ができるようになります。ただ、集中管理方式とは異なり、リソースは動的に追加されていくため、管理者としての設定はあまりありません。
| タブ | 設定項目 | 設定値 | 設定意図 | 
|---|---|---|---|
| 設定 | 認可の有効 | オン | 認可サービスを利用するために必要 | 
| 表4 「設定」タブ | |||
| 名前 | uris | 設定意図 | 
|---|---|---|
| Default Resource | /* | ※デフォルトで作成されているリソース | 
| 表5 「認可」→「リソース」タブ | ||
| 名前 | タイプ | 設定項目 | 設定値 | 設定意図 | 
|---|---|---|---|---|
| Default Policy | js | コード | JavaScriptコード(割愛) | 特に条件なくアクセスを許可する設定 ※デフォルトで作成されているポリシー | 
| Owner Only | js | コード | JavaScriptコード(割愛) | リソースオーナーのみアクセスを許可する設定 | 
| 表6 「認可」→「ポリシー」タブ | ||||
| 名前 | タイプ | リソースタイプ | ポリシー | 設定意図 | 
|---|---|---|---|---|
| Default Permission | resource | urn:authz-uma-api:resources:default | Default Policy | ※デフォルトで作成されているパーミッション(認証済みであれば許可される) | 
| Item Permission | resource | urn:authz-uma-api:resources:item | Owner Only | 指定したリソースタイプとOwner Onlyを関連付ける設定 | 
| 表7 「認可」→「アクセス権」タブ | ||||
※ パーミッションを「リソースタイプ」で設定すると、複数のリソースをまとめて同一のパーミッションに設定できます。後述しますが、UMA方式でKeycloakにリソースを作成する際に、「urn:authz-uma-api:resources:item」というリソースタイプで作成するようにします。こうすることで、当該リソースが自動的にOwner Onlyのポリシーが適用される動きになります。
Webアプリ(クライアント)の設定とソースコードの解説
●JavaScriptアダプター(keycloak.json)の設定
このkeycloak.jsonで、JavaScriptアダプターの設定を行います。主な設定としては、第8回と同様、認可サーバのURLやレルム名、クライアント名が含まれます(表8)。この設定ファイルはエンドユーザーから参照できるパスに配置することになるため、秘匿情報(クライアントシークレットなど)を含めることはできません。このクライアントでは認可制御はなく、認証済みかどうかだけがチェックされる動きになります。
{
  "realm": "demo-authz",
  "auth-server-url": "http://sso.example.com/auth",
 "ssl-required" : "none", 
  "resource": "authz-uma-client",
  "public-client" : true
}
| パラメーター名 | 必須 | 説明 | 
|---|---|---|
| realm | ○ | クライアントが定義されているレルム名を指定 | 
| auth-server-url | ○ | 認可サーバURLを指定 | 
| ssl-required | SSLが必須かどうかを指定 今回はHTTPでアクセスを許可しているため、noneを指定 本番環境では決してこのパラメーターをnoneにしてはいけません | |
| resource | ○ | クライアント名を指定 | 
| public-client | パブリッククライアントの場合は、trueを設定 | |
| 表8 JavaScriptアダプターの設定 | ||
●RPTの取得処理、およびパーミッション申請処理の解説
RPTの取得処理および、パーミッションの申請処理は、Webアプリ側のJavaScript(uma-client.jsのsubmit関数内)で行っています。Keycloakの認可クライアントJavaScript API(keycloak-authz.js)を利用することで、Keycloakとの通信部分(RPTの取得/パーミッション申請)に関しては処理を委譲できますが、それ以外の部分に関しては、アプリケーション側で実装する必要があります。
401: function(response, statusText) {
	// HTTPレスポンスヘッダに WWW-Authenticate : UMA ... が返ってきている場合は、以降の処理継続
	var wwwAuthenticateHeader = response.getResponseHeader('WWW-Authenticate');
	if (wwwAuthenticateHeader.indexOf('UMA') >= 0) {
		var params = wwwAuthenticateHeader.split(',');
		var ticket;
		// (1)WWW-Authenticateヘッダ内のticketパラメーターを取得
		for (i = 0; i < params.length; i++) {
			var param = params[i].split('=');
			if (param[0] == 'ticket') {
				ticket = param[1].substring(1, param[1].length - 1).trim();
				break;
			}
		}
		// (2)認可リクエストインスタンスを生成し、取得したticketを設定
		var authorizationRequest = {};
		authorizationRequest.ticket = ticket;
		// (3)パーミッション申請の有無を設定
		if (submitRequest) {
			authorizationRequest.submitRequest = submitRequest;
		} else {
			authorizationRequest.submitRequest = false;
		}
		// (4)認可サーバへ認可リクエスト送信
		authorization.authorize(authorizationRequest).then(function (rpt) {
		// パーミッション申請でなければ
			if (!submitRequest) {
		// (5)取得したRPTを使って当初のリクエストをリトライ
			submit(requestPath, method, rpt);
			}
		}, function () {
			// RPTが取得できない場合はアクセス権限がないので、401エラーをそのまま返す
			if (!submitRequest) {
				$(".resultConsole").text("<HTTPリクエスト>\n");
				$(".resultConsole").append(method + " " + requestUri + "\n\n");
				$(".resultConsole").append("<HTTPレスポンス>\n");
				$(".resultConsole").append("ステータス : 401 error\n");
				document.getElementById("resultMessage").value = "リソースの" + operationName[method] + "権限がありません";
			}
		}, function () {
			$('.resultConsole').text("リクエスト失敗!");
		});
(1)リソースへのアクセスで401応答が返ってきた場合は、HTTPヘッダの「WWW-Authenticate: UMA」というヘッダ内に、パーミッションチケットが戻ってきます。ここでは、ヘッダ内のticketパラメーター部分を抽出しています。
(2)認可リクエストインスタンスを生成して、ticket属性に(1)のパーミッションチケットを設定します。
(3)認可リクエストインスタンスのsubmitRequest属性により、RPT取得処理なのか、権限申請なのかを切り替えられます。RPT取得の場合は、submitRequest属性をfalseに、権限申請の場合は、trueに設定します。
(4)Keycloakの認可クライアントJavaScript APIを利用して、認可リクエストを送信します。当該ユーザーにリソースへのアクセス権があり、RPTが正常に取得できた場合、コールバック関数により、1番目のfunctionが呼び出されます。権限エラーの場合は、2番目のfunctionが呼び出されます。アクセス権がない場合/権限申請を行った場合のどちらも、こちらのfunctionが呼び出されます。3番目のfunctionは、サーバエラーなどの異常が発生した場合に呼び出されます。
(5)権限申請でない場合は、取得したRPTを使用して、当初のリソースへのアクセスをリトライします。適切なRPTを付与してリクエストを送信した場合には、アクセスが許可されます。
※ 認可クライアントJavaScript API(keycloak-authz.js)の利用方法については、こちらのページも併せてご参照ください。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
 なぜ「シングルサインオン」が必要なのか? なぜ「シングルサインオン」が必要なのか?
 企業でのWebサービスの実現が具体的になるにつれ、パスワード/IDマネジメントが重視されるようになり、「シングル・サインオン」がますます注目を集めている。この連載では、シングル・サインオンの実践ステップなど具体的な考え方を紹介する。また、メタディレクトリやLDAPなど「ディレクトリ統合」をキーワードとしてシングル・サインオンを実現するための技術を分かりやすく解説する。(編集部)
 第1回 もはや企業のID管理で避けては通れない「IDaaS」とは? 第1回 もはや企業のID管理で避けては通れない「IDaaS」とは?
 これまで社内設置が当たり前だったアイデンティティ(ID)管理/認証システム。でも「クラウド」「モバイル」に代表される激烈な変化に対応できる、と本当に思っていますか? ID管理/シングルサインオンの新たな選択肢「IDaaS」について解説する連載開始!
 強力なSSOを実現するXML認証・認可サービス(SAML) 強力なSSOを実現するXML認証・認可サービス(SAML)
 
 OpenIG、OpenDJと連携したOpenAMの新機能 OpenIG、OpenDJと連携したOpenAMの新機能
 今回は、OpenAMの姉妹製品で既存アプリケーションを改修せずにシングルサインオンを可能にする「OpenIG」と、OpenAMのデフォルトデータストアである「OpenDJ」について解説します。

