クライアントアプリケーションは、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
以上で必要なアプリケーションの起動が完了します。
Copyright © ITmedia, Inc. All Rights Reserved.