5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

KeycloakへSpring Bootアプリケーションから接続

Last updated at Posted at 2020-07-05

はじめに

ここでは、Keycloakをインストール・設定し、Spring Bootアプリケーションから接続することを試してみます。
メモ書きなので説明は必要最小限です(暇なときに説明を書くかも)

環境

使用した環境とバージョンは以下のとおりです。

  • CentOS 7.5(Keycloak)
  • Keycloak 10.0.2
  • Spring Boot 2.3.1

作成するSpring BootアプリケーションはローカルのWindows上で開発・実行します。

Keycloakインストール

Keycloakのインストールの前に、まずOpenJDK(1.8)をインストールします。

# yum install java

次のKeycloakのインストールですが、下のURLからモジュール(zip)をダウンロードし、サーバへ展開するだけです。

今回ダウンロードしたのは「keycloak-10.0.2.zip」です。

# unzip keycloak-10.0.2.zip 

Keycloakの起動と設定

Keycloakを起動する前に管理者アカウント(admin)を作成します。

# cd keycloak-10.0.2
# ./bin/add-user-keycloak.sh -u admin
Press ctrl-d (Unix) or ctrl-z (Windows) to exit
Password: 
Added 'admin' to '/opt/keycloak-10.0.2/standalone/configuration/keycloak-add-user.json', restart server to load user

次にKeycloakを起動します。ローカル以外からもアクセスできるように「-b 0.0.0.0」をつけて起動しています。

# ./bin/standalone.sh -b 0.0.0.0
~省略~
00:35:51,363 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
00:35:51,363 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
00:35:51,363 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 10.0.2 (WildFly Core 11.1.1.Final) started in 22714ms - Started 591 of 889 services (606 services are lazy, passive or on-demand)

起動後、以下のURLをブラウザから開きます。

  • http://[ホスト名]:8080/auth/

ブラウザでは以下の画面が開きます。

image.png

[Administration Console]をクリックするとログイン画面へ遷移します。

image.png

作成していた管理者アカウント(admin)でログインします。

image.png

ログイン後、最初にレルム(realm)を作成します。
ここでは"test realm"としています。

image.png

外部アプリ用のクライアントを作成します。
[Clients]タブを選択し、[Create]をクリックします。

image.png

Client IDを入力します。ここでは"login-app"としています。

image.png

作成完了後、作成したClientを一覧から選択し、"Valid Redirect URIs"を"http://localhost:8081/*"に変更しています。これが今回作成するSpring BootアプリケーションのURIとなります。

image.png

ロール作成

次にロールを作成するために[Roles]タブを選択し、[Add Role]をクリックします。

image.png

ロール名(user)を入力し、[Save]をクリックします。

image.png

ユーザ作成

ユーザを作成するために[Users]タブを選択し、[Add user]をクリックします。

image.png

Usernameに[user1]を入力し、[Save]をクリックします。

image.png

[Credentials]タブを選択し、パスワードを入力します。

image.png

image.png

ロールとユーザの紐づけ

作成したユーザ(user1)をロール(user)に紐づけるため、[Role Mappings]タブを選択し、user1を[Available Roles]から[Assigned Roles]へ移動します。

image.png

Spring BootでKeycloakを使用

Keycloakクライアントアダプターを使用してSpring Bootに接続します。

pom.xml

以下のpom.xmlを持つMavenプロジェクトを作成します。

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>test</groupId>
    <artifactId>spring-boot-keycloak</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>

    <properties>
        <keycloak-adapter-bom.version>10.0.2</keycloak-adapter-bom.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.keycloak.bom</groupId>
                <artifactId>keycloak-adapter-bom</artifactId>
                <version>${keycloak-adapter-bom.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.5.1</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

メインアプリ

今回のメインとなるアプリケーションクラスです。
普通のSpring Bootのアプリケーションです。

java.App.java
@SpringBootApplication
public class App {

    public static void main(String... args) {
        SpringApplication.run(App.class, args);
    }

}

コントローラとHTMLファイルの作成

Controller(コントローラ)クラスを以下のように作成。
"/" -> index.html, "hello" -> hello.htmlを読み込むようにしています。

WebController.java
@Controller
public class WebController {

    @GetMapping(path = "/")
    public String index() {
        return "index";
    }

    @GetMapping(path = "/hello")
    public String customers(Principal principal, Model model) {

        model.addAttribute("username", principal.getName());
        return "hello";
    }

}

index.htmlとhello.htmlはJavaテンプレートエンジンであるThymeleafを使用しています。
index.htmlにアクセスするとログインリンクが出て、リンクをクリックするとKeyCloakによるログインの後、hello.htmlに遷移するようにしています。

index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
	<div class="container">
		<div>
			<h1>Portal</h1>
		</div>
		<div>
			<a th:href="@{/hello}">Login</a>
		</div>
	</div>
</body>
</html>

hello.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
	<div id="container">
		<h1>
			Hello, <span th:text="${username}"></span>
		</h1>
	</div>
</body>
</html>

Keycloakとアプリケーションの設定

application.propertiesは以下のように設定しています。

application.properties
# server port
server.port=8081

# Keycloak
keycloak.auth-server-url=http://[Keycloakサーバのホスト名]:8080/auth
# レルム名を設定する。
keycloak.realm=test realm
# クライアントIDを設定する。
keycloak.resource=login-app
keycloak.public-client=true
## OpenID ConnectのIDトークン属性を設定。
keycloak.principal-attribute=preferred_username

Keycloakクライアントアダプター

Keycloakクライアントアダプター(keycloak-spring-security-adapter)を使用して、アクセス制御する設定を行います。

SecurityConfig.java
@KeycloakConfiguration
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider provider = keycloakAuthenticationProvider();
        provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(provider);
    }

    // Spring Security AdapterとSpring Boot Adapterを一緒に使用する場合、application.propertiesから
    // 設定情報を取得するために必要。
    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
            .antMatchers("/hello*")
            .hasRole("user")
            .anyRequest().permitAll();
    }
}

ポイントは以下の箇所で、"/hello*"にマッチした場合、"user"ロールを持っている場合のみ認可するようにしています。


        http.authorizeRequests()
            .antMatchers("/hello*")
            .hasRole("user")
            .anyRequest().permitAll();

プログラム作成は以上で完了です。

作成したSpring Bootアプリケーションの起動

作成したSpring Bootアプリケーションの起動するために以下のコマンドを実行します。

mvn clean spring-boot:run

起動後、以下のURLでSpring Bootアプリケーションへアクセスします。

アクセスすると、以下のログインリンクがある画面が表示されます。

image.png

ここでリンクをクリックすると、「/hello」とマッチしてKeycloakでの認証にうつります。ログイン画面ではKeycloakの管理コンソールで作成した、"user"ロールを持つ"user1"でログインします。

image.png

初めてのログインの場合は以下のようにパスワードの変更が表示されます。

image.png

ログインに成功すると、以下のようにユーザ名を表示するだけの画面へ遷移するようになっています。

image.png

参考

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?