1. 概要

このチュートリアルでは、 Keycloakサーバーのセットアップ、Spring Bootアプリケーションの接続、およびSpringSecurityでの使用の基本について説明します。

2. Keycloakとは何ですか?

Keycloakは、最新のアプリケーションとサービスを対象としたオープンソースのIDおよびアクセス管理ソリューションです。

Keycloakは、シングルサインオン(SSO)、IDブローカリングとソーシャルログイン、ユーザーフェデレーション、クライアントアダプター、管理コンソール、アカウント管理コンソールなどの機能を提供します。 Keycloakの詳細については、公式ページをご覧ください。

このチュートリアルでは、Keycloakの管理コンソールを使用して、Keycloakクライアントアダプタを使用してSpring Bootを設定および接続します。

3. Keycloakサーバーのセットアップ

3.1. Keycloakのダウンロードとインストール

選択できるディストリビューションはいくつかあります。 ただし、このチュートリアルでは、スタンドアロンバージョンを使用します。

Keycloak-13.0.1スタンドアロンサーバーディストリビューションを公式ソースからダウンロードしましょう。

スタンドアロンサーバーディストリビューションをダウンロードしたら、ターミナルからKeycloakを解凍して起動できます。

unzip keycloak-13.0.1.zip 
cd keycloak-13.0.1/bin
./standalone.sh -Djboss.socket.binding.port-offset=100

./standalone.shを実行すると、Keycloakはサービスを開始します。 Keycloak 13.0.1(WildFly Core 15.0.1.Final)started を含む行が表示されると、起動が完了したことがわかります。

それでは、ブラウザを開いてアクセスしてみましょう http:// localhost:8180。 管理ログインを作成するためにhttp:// localhost:8180/authにリダイレクトされます。

パスワードzaq1!QAZを使用してinitial1という名前の初期管理者ユーザーを作成しましょう。 作成をクリックすると、ユーザー作成というメッセージが表示されます。

これで、管理コンソールに進むことができます。 ログインページで、最初の管理者ユーザーの資格情報を入力します。

3.2. レルムの作成

ログインに成功すると、コンソールに移動し、デフォルトのMasterレルムが開きます。

ここでは、カスタムレルムの作成に焦点を当てます。

左上隅に移動して、[レルムの追加]ボタンを見つけましょう。

次の画面で、 SpringBootKeycloak:という新しいレルムを追加しましょう。

作成ボタンをクリックすると、新しいレルムが作成され、そこにリダイレクトされます。 次のセクションのすべての操作は、この新しいSpringBootKeycloakレルムで実行されます。

3.3. クライアントの作成

次に、[クライアント]ページに移動します。 下の画像でわかるように、 Keycloakには、すでに組み込まれているクライアントが付属しています。

アプリケーションに新しいクライアントを追加する必要があるため、[作成]をクリックします。 新しいクライアントログインアプリを呼び出します:

次の画面では、このチュートリアルの目的のために、以下を除くすべてのデフォルトを残します有効なリダイレクトURIフィールド。 このフィールドには、認証にこのクライアントを使用するアプリケーションURLが含まれている必要があります :

後で、このクライアントを使用するポート8081で実行されるSpring Bootアプリケーションを作成します。 したがって、上記の http:// localhost:8081 /*のリダイレクトURLを使用しました。

3.4. ロールとユーザーの作成

Keycloakはロールベースのアクセスを使用します。 したがって、各ユーザーには役割が必要です。

そのためには、ロールページに移動する必要があります。

次に、userロールを追加します。

これで、ユーザーに割り当てることができる役割ができましたが、まだユーザーがいないため、 [ユーザー]ページに移動して追加します:

user1:という名前のユーザーを追加します

ユーザーが作成されると、詳細が記載されたページが表示されます。

これで、資格情報タブに移動できます。 初期パスワードをxsw2@WSXに設定します。

最後に、ロールマッピングタブに移動します。 userロールをuser1に割り当てます。

4. KeycloakのAPIを使用したアクセストークンの生成

Keycloakは、アクセストークンを生成および更新するためのRESTAPIを提供します。 このAPIを使用して、独自のログインページを簡単に作成できます。

まず、POSTリクエストを次のURLに送信して、Keycloakからアクセストークンを取得する必要があります。

http://localhost:8180/auth/realms/SpringBootKeycloak/protocol/openid-connect/token

リクエストには、この本文がx-www-form-urlencoded形式である必要があります。

client_id:<your_client_id>
username:<your_username>
password:<your_password>
grant_type:password

それに応じて、access_tokenrefresh_tokenを取得します。

アクセストークンは、Keycloakで保護されたリソースへのすべてのリクエストで、Authorizationヘッダーに配置するだけで使用する必要があります。

headers: {
    'Authorization': 'Bearer' + access_token
}

アクセストークンの有効期限が切れたら、POSTリクエストを上記と同じURLに送信することで更新できますが、ユーザー名とパスワードの代わりに更新トークンが含まれています。

{
    'client_id': 'your_client_id',
    'refresh_token': refresh_token_from_previous_request,
    'grant_type': 'refresh_token'
}

Keycloakは、新しいaccess_tokenおよびrefresh_token。でこれに応答します。

5. SpringBootアプリケーションの作成

5.1. 依存関係

最新のSpringBootKeycloak Starterの依存関係は、MavenCentralにあります。

Keycloak SpringBootアダプターはSpringBootの自動構成を利用するため、必要なのはKeycloakSpringBootスターターをプロジェクトに追加することだけです。

依存関係のXML要素内で、Spring Bootを使用してKeycloakを実行するには、次のものが必要です。

<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>

依存関係のXML要素の後に、KeycloakにdependentencyManagementを指定する必要があります。

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

次の組み込みコンテナが現在サポートされており、Spring Boot Keycloak Starterを使用している場合は、追加の依存関係は必要ありません。

  • Tomcat
  • 逆流
  • 桟橋

5.2. ThymeleafWebページ

WebページにはThymeleafを使用しています。

3つのページがあります。

  • external.html –一般向けの外部向けWebページ
  • customers.html –アクセスがuserの役割を持つ認証済みユーザーのみに制限される内部向けのページ。
  • layout.html – 2つのフラグメントで構成されるシンプルなレイアウトで、外向きのページと内向きのページの両方に使用されます

Thymeleafテンプレートのコードは、Githubで入手できます。

5.3. コントローラ

Webコントローラーは、内部URLと外部URLを適切なThymeleafテンプレートにマップします。

@GetMapping(path = "/")
public String index() {
    return "external";
}
    
@GetMapping(path = "/customers")
public String customers(Principal principal, Model model) {
    addCustomers();
    model.addAttribute("customers", customerDAO.findAll());
    model.addAttribute("username", principal.getName());
    return "customers";
}

パス/Customers の場合、リポジトリからすべての顧客を取得し、その結果を属性としてModelに追加します。 後で、Thymeleafで結果を繰り返し処理します。

ユーザー名を表示できるようにするために、プリンシパルも挿入しています。

ここでは、表示する生データとして顧客を使用していることに注意してください。それ以上のものはありません。

5.4. Keycloakの構成

基本的な必須構成は次のとおりです。

keycloak.auth-server-url=http://localhost:8180/auth
keycloak.realm=SpringBootKeycloak
keycloak.resource=login-app
keycloak.public-client=true

思い出したように、ポート 8180 でKeycloakを開始したため、keycloak.auth-server-urlで指定されたパスになります。 Keycloak管理コンソールで作成したレルム名を入力します。

keycloak.resource で指定する値は、管理コンソールで指定したクライアントと一致します。

使用するセキュリティ制約は次のとおりです。

keycloak.security-constraints[0].authRoles[0]=user
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*

これらの制約により、 / Customers / * へのすべての要求は、それを要求するユーザーがuserの役割を持つ認証済みユーザーである場合にのみ許可されます。

さらに、keycloak.principal-attributepreferred_usernameとして定義して、コントローラーのPrincipalに適切なユーザーを設定できます。

keycloak.principal-attribute=preferred_username

5.5. デモンストレーション

これで、アプリケーションをテストする準備が整いました。 Spring Bootアプリケーションを実行するには、Spring Tool Suite(STS)などのIDEから簡単に起動するか、ターミナルで次のコマンドを実行します。

mvn clean spring-boot:run

http:// localhost:8081 にアクセスすると、次のように表示されます。

次に、 Customers をクリックして、機密情報の場所であるイントラネットに入ります。

このコンテンツを表示する権限があるかどうかを確認するために、Keycloakを介して認証するようにリダイレクトされていることに注意してください。

user1 としてログインすると、Keycloakは user の役割を持っていることを確認し、制限されたCustomersページにリダイレクトされます。

これで、Spring BootをKeycloakに接続し、それがどのように機能するかを示すセットアップが完了しました。

ご覧のとおり、 Spring Bootは、Keycloak AuthorizationServerを呼び出すプロセス全体をシームレスに処理しました。 アクセストークンを自分で生成するためにKeycloakAPIを呼び出す必要はなく、保護されたリソースのリクエストでAuthorizationヘッダーを明示的に送信する必要もありませんでした。

次に、既存のアプリケーションと組み合わせてSpringセキュリティを使用する方法を確認します。

6. 春のセキュリティ

Keycloak Spring Security Adapterがあり、それはすでにSpring BootKeycloakStarter依存関係に含まれています。 SpringセキュリティをKeycloakと統合する方法を見ていきます。

6.1. 依存

SpringBootでSpringSecurityを使用するには、次の依存関係を追加する必要があります。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.6.1</version>
</dependency>

最新のSpringBootStarter Securityリリースは、MavenCentralにあります。

6.2. 構成クラス

Keycloakは、WebSecurityConfigurerインスタンスを作成するための便利な基本クラスとしてKeycloakWebSecurityConfigurerAdapterを提供します。

Spring Securityで保護されたアプリケーションには、 WebSecurityConfigurerAdapter:を拡張する構成クラスが必要なため、これは便利です。

@KeycloakConfiguration
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

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

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

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

上記のコードでは、メソッド configureGlobal() SimpleAuthorityMapper をタスクして、ロールの前にROLE_。が付いていないことを確認します。

@Configuration
public class KeycloakConfig {

    @Bean
    public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }
}

ここで、 keycloakConfigResolver は、デフォルトのkeycloak.json。の代わりにSpringBootプロパティファイルサポートを使用することを定義しています。

Spring Securityを使用してセキュリティ制約を設定したので、プロパティファイルで以前に配置したこれらのセキュリティ制約を削除またはコメント化できます。

#keycloak.security-constraints[0].authRoles[0]=user
#keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*

これで、認証後、前に見たのと同じように、内部の顧客ページにアクセスできるようになります。

7. 結論

この記事では、Keycloakサーバーを構成し、SpringBootアプリケーションで使用しました。

また、Spring Securityを設定し、Keycloakと組み合わせて使用する方法も学びました。 この記事に示されているコードの動作バージョンは、Githubから入手できます。