概要
Keycloakアドベンドカレンダー3日目は、Spring BootベースのWebアプリケーションの認証をKeycloakに委譲する手順について説明します。KeycloakにはSpring Boot用のアダプターがあり、簡単にSpring BootベースのWebアプリケーションをセキュリティ保護できます。これにより、最新の認証プロトコルである**「OpenID Connect」**(以下OIDC)に対応したセキュアなSpring Bootアプリケーションとなります。
連携ができると、ユーザーはOIDCの「End User」に、Spring BootベースのWebアプリケーションはOIDCの「Relying Party」に、KeycloakはOIDCの「OpenID Provider」になります。
はじめる前に
このチュートリアルの操作をはじめる前に、Keycloakのセットアップを完了し、管理者ユーザーを作成する必要があります。Keycloakアドベンドカレンダー2日目の記事を参考にそれらの作業を実施しておいて下さい。また、Webアプリケーションのビルドと起動にGradleかMavenを使用しますので、いずれかをインストールしておいて下さい。
なお、今回はKeycloakもSpring BootベースのWebアプリケーションもlocalhostに構築します。
連携の手順
連携の手順は以下のようになります。これが完了したら、動作確認をします。
- Keycloakの設定
- 1.1. レルムの作成
- 1.2. クライアントの作成
- 1.3. ロールの作成
- 1.4. ユーザーの作成とロールの割り当て
- 簡単なSpring Bootアプリケーションの作成
- 2.1. Spring Initializrでアプリの雛形作成
- 2.2. クラスとhtmlの作成
- 2.3. アプリのKeycloak連携の設定
1.1. レルムの作成
レルムを作成する前にレルムについて簡単に説明します。**Keycloakにおける「レルム(Realm)」とは、ユーザー、ロール、接続するデータストア(LDAPなど)などをまとめるための範囲を意味します。**ユーザーは、レルム内に作成することができ、認証の方法などをレルム単位で定義することができます。デフォルトでは、「Master」というレルムが一つあり、その後追加する全てのレルムを包含して管理することができます。「Master」レルムは、レルムの階層内で最も高いレベルであり、スーパー管理者(初回セットアップ時に作成した管理者アカウント)で管理できます。
「Master」レルムを使ってユーザーなどを管理することもできますが、基本的にはレルムを作成することが推奨されているので、まずはレルムを作成します。なお、「Master」レルムは削除することもできます。
http://localhost:8080/auth/admin/にアクセスして、管理者アカウントでKeycloak管理コンソールにログインします。
左側の一番上コーナーにある「Master」と表示されたドロップダウン・メニューで、「レルムの追加」をクリックします。
レルム追加ページが開きます。新規レルムを作成するので、レルム名に「demo」と入力して「作成」ボタンをクリックします。
レルムを作成すると、管理コンソールのメインページに遷移します。現在のレルムは「demo」となっているはずです。
左上隅のドロップダウン・メニューをクリックして、管理下にあるmasterレルムと今作成したレルムを切替えることができます。
1.2. クライアントの作成
次に、クライアントを作成します(※)。今回のケースにおいて、クライアントとは、OIDCで規定された「Relying Party」(OIDC 1.0のベースとなっているOAuth 2.0では「クライアント」とも言います)であり、Spring Bootアプリケーションのことになります。
※正確に言うと、クライアントのプロファイルを作成します。クライアント自体は、後述する「Spring Initializr」などを使って作成します。 |
左メニューバーで「クライアント」をクリックします。クライアントの一覧画面が表示されるので、「作成」ボタンをクリックします。
「sample-app」と入力して、「保存」ボタンをクリックします。
「有効なリダイレクトURI」に「http://localhost:8081/hello
」と入力します。
1.3. ロールの作成
次に、ユーザーに割り当てるロールを作成します。このロールが割り当てられたユーザーだけが、Spring Bootアプリケーションにアクセスできるように、後で設定を行います。
ロールは、ユーザーの役割を意味し、ユーザーのタイプやカテゴリを識別するために利用します。管理者、ユーザー、マネージャー、従業員などが、組織内に存在する典型的なロールです。アプリケーションでは、ユーザーの管理が難しくならないように、個々のユーザーではなく特定のロールにアクセス権を割り当てることがよくあります。 |
左メニューバーで「ロール」をクリックします。ロールの一覧画面が表示されるので、「作成」ボタンをクリックします。
「ロール名」に「user」と入力して「保存」ボタンをクリックします。
1.4. ユーザーの作成とロールの割り当て
最後に、ユーザーを作成し、ロールを割り当てます。左メニューバーで「ユーザー」をクリックします。ユーザーの一覧画面が表示されるので、「作成」ボタンをクリックします。
ユーザー一覧のページが開きます。空のユーザーリストの右側にある「ユーザーの追加」をクリックします。
必須入力のユーザー名のみを入力して、「保存」ボタンをクリックすると、新規ユーザーの管理ページが開きます。
次に、新規ユーザーのパスワードを設定します。「クレデンシャル」タブをクリックします。
新しいパスワードとパスワード(確認)を入力すると、赤い「パスワードリセット」ボタンが表示されます。この時、「一時的」は「オフ」に変更して下さい。これにより、初回ログイン時にパスワードを変更する必要がなくなります。
「パスワードリセット」ボタンをクリックすると、パスワードがリセットされます。
最後に「ロールマッピング」のタグをクリックして、「使用可能なロール」の中にあるuser
を「アサイン済みロール」に移動します。
以上でKeycloakの設定は完了です。
2.1. Spring Initializrでアプリの雛形作成
次に、Spring Bootアプリケーションを作成します。Spring Bootアプリケーションの雛形作成には、Spring Initializrを使用します。Spring Initializrのページにアクセスして下さい。
上の画面のように以下を入力、選択してから、「Generate Project」ボタンをクリックして下さい。
項目 | 設定値 |
---|---|
Project | Gradle ProjectまたはMaven Project |
言語 | Java |
Dependencies | Web、Thymeleaf、DevTools、Keycloak |
Group | com.example |
Artifact | sample-app |
圧縮ファイルがダウンロードされるので、適当なディレクトリに解凍して下さい。
2.2. クラスとhtmlの作成
まずはトップページの静的なHTMLを作成します。src/main/resources/static/
にindex.html
というHTMLファイルを次のような内容で作成します。
<html>
<head>
<title>Sample Application</title>
</head>
<body>
<h1>Sample Application</h1>
<a href="/hello">Go to hello page!</a>
</body>
</html>
次にこの画面から呼び出されるコントローラーと画面を作成します。コントローラーは、src/main/java/com/example/sampleapp/
にHelloController.java
というファイル名で次のような内容とします。
package com.example.sampleapp;
import java.util.Locale;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
class HelloController {
@RequestMapping(value = "/hello")
public ModelAndView hello(HttpSession ses, ModelAndView mav, Locale locale) {
mav.setViewName("hello");
mav.addObject("message", "Hello! Spring Boot and Keycloak!");
return mav;
}
@RequestMapping(value = "/logout")
public String logout(HttpServletRequest request) throws ServletException {
request.logout();
return "redirect:/";
}
}
このコントローラから呼び出される画面は、src/main/resources/templates/
にhello.html
というHTMLファイルで作成します。
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:with="lang=${#locale.language}" th:lang="${lang}">
<h1>Hello</h1>
<p th:text="${message}" /><br />
<p>
<a href="/logout">Logout</a>
</p>
</html>
ディレクトリ構成は以下のようになっています。
これでサンプルのWebアプリケーションは完成しました。
2.3. アプリのKeycloak連携の設定
最後に、作成したWebアプリケーションにKeycloakと連携するための設定を行います。/src/main/resources/application.properties
に以下の定義を追加して下さい。
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=demo
keycloak.public-client=true
keycloak.resource=sample-app
keycloak.security-constraints[0].authRoles[0]=user
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/hello/
server.port=8081
http://localhost/hello/以下へのアクセスには認証が必要で、そのユーザーにはロール「user」が必要であることを定義しています。最後のプロパティは、このアプリケーションがポート8081でリッスンされることを指定しています。
以上で全ての設定は完了です。
動作確認
では、動作確認してみましょう。次のコマンドで作成したWebアプリケーションを起動します。
Gradleの場合
$ gradle bootRun
Mavenの場合
$ mvn spring-boot:run
http://localhost:8081にアクセスすると、次のような画面が表示されます。
「Go to hello page!」のリンクをクリックすると、Keycloakのログイン画面にリダイレクトされます。
作成したユーザーでログインして下さい。これまでの設定が適切にできていれば、次のような画面が表示されます。
最後に
このようにSpring BootベースのWebアプリケーションの認証をKeycloakに委譲するのはとても簡単です。簡単なだけでなく、標準的でセキュアなログイン処理を実装したことにもなります。
今回はSpring Boot Adapterを使用しましたが、Spring Security Adapterというものもあり、Spring Boot Keycloak Starterに含まれています。これについては、また別の機会に説明します(その機会があれば...)。