Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その12 )( Spring Boot Actuator を導入する )
概要
記事一覧はこちらです。
Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その11 )( HikariCP のコネクションプーリングの情報を JMX で取得できるようにする ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Spring Boot Actuator を導入します。
- Spring Boot + npm + Geb で入力フォームを作ってテストする ( その76 )( Spring Boot Actuator を導入する ) を参考に進めます。
- ksbysample-webapp-lending では Spring Security で form login を設定していますが、Spring Actuator の Endpoint には Basic 認証を設定します。
- 今回は prometheus の endpoint も設定して、次回以降に Docker で Prometheus+Grafana の環境を構築して表示させてみる予定です。
参照したサイト・書籍
Spring Boot Reference Guide - 51.3 Securing HTTP Endpoints
https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#production-ready-endpoints-securitySpring Security Reference - 6.10 Multiple HttpSecurity
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#multiple-httpsecurityMultiple Authentication Providers in Spring Security
https://www.baeldung.com/spring-security-multiple-auth-providers
目次
- build.gradle を変更する
- WebSecurityConfig.java を変更して
/actuator/**
にのみ Basic 認証を設定する - application.properties を変更する
- 動作確認
- 次回は。。。
手順
build.gradle を変更する
build.gradle の以下の点を変更します。
plugins { .......... id "de.undercouch.download" version "3.4.3" id "com.gorylenko.gradle-git-properties" version "1.5.2" } .......... dependencies { .......... implementation("org.springframework.boot:spring-boot-starter-amqp") implementation("org.springframework.boot:spring-boot-starter-actuator") runtimeOnly("org.springframework.boot:spring-boot-devtools") .......... implementation("org.codehaus.janino:janino") implementation("io.micrometer:micrometer-registry-prometheus") testImplementation("org.springframework.boot:spring-boot-starter-test") ..........
- plugins block の以下の点を変更します。
id "com.gorylenko.gradle-git-properties" version "1.5.2"
を追加します。
- dependencies block の以下の点を変更します。
implementation("org.springframework.boot:spring-boot-starter-actuator")
を追加します。- spring-boot-devtools は runtimeOnly で記述すべきなのに変更するのを忘れていることに気づきました。
implementation("org.springframework.boot:spring-boot-devtools")
→runtimeOnly("org.springframework.boot:spring-boot-devtools")
に変更します。 implementation("io.micrometer:micrometer-registry-prometheus")
を追加します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
WebSecurityConfig.java を変更して /actuator/**
にのみ Basic 認証を設定する
src/main/java/ksbysample/webapp/lending/config/WebSecurityConfig.java の以下の点を変更します。
@Configuration public class WebSecurityConfig { .......... @Configuration @Order(1) public static class ActuatorWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http // Spring Actuator の Endpoint のみ Basic認証を設定する .requestMatcher(EndpointRequest.toAnyEndpoint()) .authorizeRequests() .anyRequest().hasRole("ENDPOINT_ADMIN") .and() .httpBasic(); } } @Configuration public static class FormLoginWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 認証の対象外にしたいURLがある場合には、以下のような記述を追加します // 複数URLがある場合はantMatchersメソッドにカンマ区切りで対象URLを複数列挙します // .antMatchers("/country/**").permitAll() .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() .antMatchers("/fonts/**").permitAll() .antMatchers("/html/**").permitAll() .antMatchers("/encode").permitAll() .antMatchers("/urllogin").permitAll() .antMatchers("/webapi/**").permitAll() .antMatchers("/springMvcMemo/**").permitAll() .antMatchers("/sessionsample/**").permitAll() .antMatchers("/textareamemo/**").permitAll() .antMatchers("/sample/**").permitAll() .anyRequest().hasAnyRole("USER", "ADMIN", "APPROVER"); http.formLogin() .loginPage("/") .loginProcessingUrl("/login") .defaultSuccessUrl(DEFAULT_SUCCESS_URL) .usernameParameter("id") .passwordParameter("password") .successHandler(new RoleAwareAuthenticationSuccessHandler()) .failureHandler(new ForwardAuthenticationFailureHandler("/")) .permitAll() .and() .logout() .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/") .deleteCookies("SESSION") .deleteCookies("remember-me") .invalidateHttpSession(true) .permitAll() .and() .rememberMe() .key(REMEMBERME_KEY) .tokenValiditySeconds(60 * 60 * 24 * 30); } } .......... /** * @param auth ??? * @throws Exception */ @SuppressWarnings("PMD.SignatureDeclareThrowsException") @Autowired public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception { // 必ず auth.inMemoryAuthentication() を先に書くこと auth.inMemoryAuthentication() .withUser("actuator") .password("{noop}xxxxxxxx") .roles("ENDPOINT_ADMIN"); auth.authenticationProvider(daoAuhthenticationProvider()) .userDetailsService(userDetailsService); } }
@Configuration public static class FormLoginWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { ... }
を追加し、既存の configure メソッドをこの中へ移動します。また configure メソッド内の.authenticated()
→.hasAnyRole("USER", "ADMIN", "APPROVER")
に変更して actuator 用の Role として使用する ENDPOINT_ADMIN ではログインできないようにします。@Configuration @Order(1) public static class ActuatorWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { ... }
を追加し、actuator の endpoint の Basic認証をこのクラスで設定します。- configAuthentication bean 内に
auth.inMemoryAuthentication().withUser("actuator").password("{noop}xxxxxxxx").roles("ENDPOINT_ADMIN");
を追加します。
application.properties を変更する
src/main/resources/application.properties の以下の点を変更します。
doma.dialect=org.seasar.doma.jdbc.dialect.PostgresDialect management.endpoints.web.exposure.include=health,info,loggers,prometheus spring.autoconfigure.exclude=com.integralblue.log4jdbc.spring.Log4jdbcAutoConfiguration spring.datasource.hikari.jdbc-url=jdbc:postgresql://localhost/ksbylending ..........
management.endpoints.web.exposure.include=health,info,loggers,prometheus
を追加します。
動作確認
ここまでの設定で /actuator/**
には Basic 認証が、それ以外のパスには Form 認証が行われるはずなので、確認してみます。
Tomcat を起動した後、http://localhost:8080/admin/library にアクセスするとログイン画面が表示されます。
tanaka.taro@sample.com / taro を入力して「ログイン」ボタンをクリックすると http://localhost:8080/admin/library が表示されます。
ログインしている状態から http://localhost:8080/actuator/prometheus にアクセスすると、現在ログインしている ID では ENDPOINT_ADMIN の ROLE を持っていないので 403 Forbidden が返ってきます。
画面右上の「ログアウト」リンクをクリックしてログアウトしてから再度 http://localhost:8080/actuator/prometheus にアクセスすると、Basic 認証のダイアログが表示されます。
actuator / xxxxxxxx を入力して「OK」ボタンをクリックすると /actuator/prometheus が出力する情報が表示されます。
次回は。。。
Docker で Prometheus+Grafana の環境を構築して Spring Actuator で収集したメトリックスを表示させてみます。
履歴
2018/10/29
初版発行。
2018/11/20
* Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その13 )( Remember Me 認証が使えなくなっていたので調査・修正する ) の結果を反映して auth.inMemoryAuthentication()
を書く位置を修正しました。