クライアントアプリケーションは、Spring Frameworkとkeycloak-spring-security-adapterを利用して構築します。keycloak-spring-security-adapterは、Spring Frameworkのセキュリティ用フレームワークである「Spring Security」の機能を拡張したライブラリで、OIDCによるアクセストークンの取得やアクセス制御、アクセストークン付きアクセスの機能を提供します。
ここでは、Springアプリケーションへのアダプターのインストールとアクセス制御の設定方法、Keycloakで保護されたAPIサーバへのアクセス方法について説明します。
最初に、keycloak-spring-security-adapterを利用するため、「Maven」の依存関係を追加します。以下の依存関係を「pom.xml」ファイルに追加します。
<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-spring-security-adapter</artifactId>
    <version>3.2.0.Final</version>
</dependency>
APIサーバと同様に「keycloak.json」ファイルをダウンロードして、「WEB-INF」ディレクトリに配置します。今回の「keycloak.json」ファイルは以下のような内容になっています。
{
  "realm": "sample",
  "auth-server-url": "http://localhost:8080/auth",
  "ssl-required": "external",
  "resource": "client-app",
  "credentials": {
    "secret": "password"
  }
}
keycloak-spring-security-adapterでは、KeycloakWebSecurityConfigurerAdapterクラスを継承したSecurityConfigurationクラスを利用して、アクセス制御の設定を行います。
今回のサンプルアプリケーションでは、以下のように設定しています。
                                            
@KeycloakConfiguration
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider provider = keycloakAuthenticationProvider();
        provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(provider);
    }
                                               
    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }
                                               
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
            .authorizeRequests()
            .antMatchers("/app**").hasAnyRole("user", "admin")
            .antMatchers("/app/user**").hasAnyRole("user")
            .antMatchers("/app/admin**").hasRole("admin")
            .anyRequest().permitAll();
    }
}
今回は、「/」「/app」および「/app/user」「/app/admin」の4つのページを作成しているため、それぞれのページにロールによるアクセス制御を行っています。
APIサーバへアクセスするには、アクセストークン付きのHTTPアクセスが必要になります。これには、Keycloakのクライアントアダプターが提供するKeycloakRestTemplateクラスを利用します。このクラスは、Spring Frameworkが提供する「RestTemplate」というクラスを拡張したもので、セッションにひも付くアクセストークンの情報を追加してくれます。
まず、SecurityConfigurationクラスで以下のように「@Bean」を定義します。
    @Autowired
    public KeycloakClientRequestFactory keycloakClientRequestFactory;
                         
    @Bean
    public KeycloakRestTemplate keycloakRestTemplate() {
        return new KeycloakRestTemplate(keycloakClientRequestFactory);
    }
そして、サービス側で「@Autowired」を定義することで、KeycloakRestTemplateを利用することができます。
    @Autowired
    private KeycloakRestTemplate template;
                                                
    private static String endpoint = "http://localhost:8180/service/sample/";
    public List<String> getHello() {
        ResponseEntity<String[]> response = template.getForEntity(endpoint, String[].class);
        return Arrays.asList(response.getBody());
    }
@Beanや@AutowiredといったキーワードはSpring Frameworkに関するものであり、本連載では説明しません。これらの動作に関する詳細な説明は、Spring Frameworkの公式ドキュメントなどを参照してください。
作成したアプリケーションの動作を確認するために、APIサーバとクライアントアプリケーションを起動してみます。
まず、APIサーバを実行するWildflyサーバを起動します。Wildflyはデフォルトで「8080」ポートで起動するため、そのまま起動するとポートが重複して起動できません。そこで、「port-offset」というパラメータを指定して起動します。
$ ./bin/standalone.sh -Djboss.socket.binding.port-offset=100
port-offsetパラメータを指定することで、Wildflyが利用する全てのポートに「100」が追加された状態で起動します。Webへのアクセスは「http://localhost:8180/」となります。
Wildflyサーバの起動後、「api-service」ディレクトリで以下のコマンドを実行することでAPIサーバのアプリケーションがWildflyにデプロイされます。
$ mvn wildfly:deploy
クライアントアプリケーションはSpring Bootアプリケーションになっているため、起動のためのアプリケーションサーバは必要ありません。ただし、Spring Bootもデフォルトでは「8080」ポートで起動してしまうので、「application.yml」ファイルを編集して、起動するポートを「9000」に変更しています。
server: port: 9000
「client-app」ディレクトリで以下のコマンドを実行すると、クライアントアプリケーションが実行されます。
$ mvn spring-boot:run
以上で必要なアプリケーションの起動が完了します。
 なぜ「シングルサインオン」が必要なのか?
なぜ「シングルサインオン」が必要なのか? 第1回 もはや企業のID管理で避けては通れない「IDaaS」とは?
第1回 もはや企業のID管理で避けては通れない「IDaaS」とは? 強力なSSOを実現するXML認証・認可サービス(SAML)
強力なSSOを実現するXML認証・認可サービス(SAML) OpenIG、OpenDJと連携したOpenAMの新機能
OpenIG、OpenDJと連携したOpenAMの新機能Copyright © ITmedia, Inc. All Rights Reserved.