Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その31 )( Spring Actuator の Basic 認証用ユーザの認証成功時には AuthenticationSuccessEvent イベントが発生しないようにする+いろいろ調整する )
概要
記事一覧はこちらです。
Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その30 )( Redis のクライアントライブラリを Jedis → Lettuce に変更する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Prometheus が Spring Actuator にアクセスした時に、コンソールにレスポンスの内容が出力されて他のログが見にくかったり、Basic 認証の成功時に AuthenticationSuccessEvent が発生して update 文が実行されたりしていたので、修正します。
- 他に以下の点を変更します。
- PostgreSQL のコンテナ起動時に毎回検索対象図書館を登録し直さなくてもよいようにします。
- build タスク実行時に PMD の
This analysis could be faster, ...
のメッセージが出力されないようにします。 - HikariCP を最新バージョンに変更して leak-detection-threshold の設定を変更します。
- spring-boot-properties-migrator が何もメッセージを出力していないので削除します。
参照したサイト・書籍
- @EventListener for AuthenticationSuccessEvent or InteractiveAuthenticationSuccessEvent not fired
https://stackoverflow.com/questions/41076500/eventlistener-for-authenticationsuccessevent-or-interactiveauthenticationsucces
目次
- Prometheus が Spring Actuator にアクセスした時に、コンソールにレスポンスの内容が出力されないようにする
- Prometheus が Spring Actuator にアクセスした時に AuthenticationSuccessEventListener#onApplicationEvent の update 文が実行されないようにする
- library_forsearch テーブルに初期データを登録して、最初に検索対象図書館を登録不要にする
- pmdMain タスク実行時の
This analysis could be faster, ...
のメッセージが出力されないようにする - HikariCP は最新の 3.3.0 を dependenceis に指定し、spring.datasource.hikari.leak-detection-threshold の値を 5000 → 60000 に変更する
runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
を削除する- 次回は。。。
手順
Prometheus が Spring Actuator にアクセスした時に、コンソールにレスポンスの内容が出力されないようにする
src/main/resources/application-develop.properties で logging.level.org.springframework.web=DEBUG を設定しているため、Prometheus が Spring Actuator にアクセスした時のレスポンスの内容もコンソールに出力されます。
このままではコンソールに大量に出力されるため、ログが全然確認できなくて調査等の時に困ったので出ないようにします。org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor の DEBUG ログなので、このクラスだけ log.level を INFO に変更して出力されないようにします。
src/main/resources/application-develop.properties に logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor=INFO
を追加します。
# Spring MVC logging.level.org.springframework.web=DEBUG logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor=INFO
Prometheus が Spring Actuator にアクセスした時に AuthenticationSuccessEventListener#onApplicationEvent の update 文が実行されないようにする
Prometheus が Spring Actuator にアクセスした時のレスポンスの内容が出力されないようにしたら、今度は Prometheus が Spring Actuator にアクセスした時に Basic 認証で成功したら ksbysample.webapp.lending.security.AuthenticationSuccessEventListener#onApplicationEvent が呼び出されて update user_info set cnt_badcredentials = 0 where mail_address = 'actuator'
文が実行されていることに気づきました。Spring Actuator の Basic 認証用ユーザの場合には AuthenticationSuccessEvent イベントが発生しないようにします。
src/main/java/ksbysample/webapp/lending/config/WebSecurityConfig.java の以下の点を変更します。
@Configuration public class WebSecurityConfig { public static final String DEFAULT_SUCCESS_URL = "/booklist"; public static final String REMEMBERME_KEY = "ksbysample-webapp-lending"; public static final String ACTUATOR_USERNAME = "actuator"; .......... /** * Spring Actuator の Basic認証用ユーザの場合には AuthenticationSuccessEvent を発生させないための * AuthenticationEventPublisher */ static class CustomAuthenticationEventPublisher extends DefaultAuthenticationEventPublisher { /** * コンストラクタ * * @param applicationEventPublisher {@link ApplicationEventPublisher} オブジェクト */ public CustomAuthenticationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { super(applicationEventPublisher); } /** * 認証成功時のメソッド * Spring Actuator の Basic認証用ユーザの場合には AuthenticationSuccessEvent を発生させない * * @param authentication {@link Authentication} オブジェクト */ @Override public void publishAuthenticationSuccess(Authentication authentication) { if (StringUtils.equals(authentication.getName(), ACTUATOR_USERNAME)) { return; } super.publishAuthenticationSuccess(authentication); } } /** * @param auth ??? * @throws Exception */ @SuppressWarnings("PMD.SignatureDeclareThrowsException") @Autowired public void configAuthentication(AuthenticationManagerBuilder auth , ApplicationEventPublisher applicationEventPublisher) throws Exception { // AuthenticationManagerBuilder#userDetailsService の後に auth.inMemoryAuthentication() を呼び出すと // AuthenticationManagerBuilder の defaultUserDetailsService に // org.springframework.security.provisioning.InMemoryUserDetailsManager がセットされて // Remember Me 認証で InMemoryUserDetailsManager が使用されて DB のユーザが参照されなくなるので、 // Remember Me 認証で使用する UserDetailsService を一番最後に呼び出す // ※今回の場合には auth.userDetailsService(userDetailsService) が一番最後に呼び出されるようにする auth.inMemoryAuthentication() .withUser(ACTUATOR_USERNAME) .password("{noop}xxxxxxxx") .roles("ENDPOINT_ADMIN"); auth.authenticationEventPublisher(new CustomAuthenticationEventPublisher(applicationEventPublisher)) .userDetailsService(userDetailsService); } }
public static final String ACTUATOR_USERNAME = "actuator";
を追加し、configAuthentication メソッド内の.withUser("actuator")
→.withUser(ACTUATOR_USERNAME)
に変更します。- DefaultAuthenticationEventPublisher を継承した CustomAuthenticationEventPublisher クラスを定義し、publishAuthenticationSuccess メソッドで Spring Actuator の Basic認証用ユーザの場合には何もしないようにします。
- configAuthentication メソッドの以下の点を変更します。
- 引数に
ApplicationEventPublisher applicationEventPublisher
を追加します。 .authenticationEventPublisher(new CustomAuthenticationEventPublisher(applicationEventPublisher))
を追加します。
- 引数に
これで update 文は実行されないようになります(DispatcherServlet の DEBUG ログだけが出ています)。
library_forsearch テーブルに初期データを登録して、最初に検索対象図書館を登録不要にする
PostgreSQL を Docker で起動して Flyway で初期データを登録するように変更しましたが、library_forsearch テーブルには初期データを登録していなかったため起動直後は検索対象図書館登録画面から図書館を選択する必要がありました。面倒なので初期データを登録するようにします。
src/main/resources/db/migration/V1.1__insert_data.sql を以下のように変更します。
.......... INSERT INTO public.user_role (role_id, user_id, role) VALUES (9, 8, 'ROLE_USER'); INSERT INTO public.library_forsearch (systemid, formal) VALUES ('Tokyo_NDL', '国立国会図書館東京本館');
INSERT INTO public.library_forsearch (systemid, formal) VALUES ('Tokyo_NDL', '国立国会図書館東京本館');
を追加します。
これで最初から「国立国会図書館東京本館」が選択された状態になります。
pmdMain タスク実行時の This analysis could be faster, ...
のメッセージが出力されないようにする
build タスクを実行した時に pmdMain タスクで This analysis could be faster, please consider using Incremental Analysis: https://pmd.github.io/pmd-6.10.0/pmd_userdocs_incremental_analysis.html
のメッセージが出力されますが、出力しないようにする方法が分かったので反映します。
build.gradle を以下のように変更します。
pmd { toolVersion = "6.10.0" sourceSets = [project.sourceSets.main] ignoreFailures = true consoleOutput = true ruleSetFiles = rootProject.files("/config/pmd/pmd-project-rulesets.xml") ruleSets = [] } pmdMain { def backupLoggerLevel doFirst { backupLoggerLevel = logger.context.level logger.context.level = LogLevel.QUIET } doLast { logger.context.level = backupLoggerLevel } }
pmdMain { ... }
の部分を追加します。
build タスクを実行すると以下のように This analysis could be faster, ...
のメッセージが出力されません。
また PMD で警告が出る場合は以下のように出力されます(WebSecurityConfig クラスで使用されない import 文が残るように変更して build しています)。
HikariCP は最新の 3.3.0 を dependenceis に指定し、spring.datasource.hikari.leak-detection-threshold の値を 5000 → 60000 に変更する
ここまでの状態で Tomcat を起動していろいろ画面を操作してみたのですが、そこそこの頻度で Connection leak detection triggered for org.postgresql.jdbc.PgConnection@4d36771 on thread http-nio-8080-exec-4, stack trace follows
のようなメッセージがコンソールに出力されることに気づきました。現在 5 秒で設定していますが、もう少し長めにするとこのエラーは出なくなるようなので 60秒に変更します。
また依存関係にある HikariCP のバージョンが Spring Boot の 2.0.6 では 2.7.9、2.1.1 だと 3.2.0 なのですが、HikariCP/CHANGES を見ると Changes in 3.0.0
に update to Micrometer 1.0.0.
という記述を見つけたので、最新の 3.3.0 に変更するとにします。
まずは build.gradle に implementation("com.zaxxer:HikariCP:3.3.0")
を追加した後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
dependencies { .......... implementation("org.flywaydb:flyway-core:5.2.4") implementation("com.zaxxer:HikariCP:3.3.0") testImplementation("org.dbunit:dbunit:2.6.0") ..........
src/main/resources/application.properties を以下のように変更します。
#spring.autoconfigure.exclude=com.integralblue.log4jdbc.spring.Log4jdbcAutoConfiguration spring.datasource.hikari.jdbc-url=jdbc:postgresql://localhost/ksbylending spring.datasource.hikari.username=ksbylending_user spring.datasource.hikari.password=xxxxxxxx spring.datasource.hikari.driver-class-name=org.postgresql.Driver spring.datasource.hikari.leak-detection-threshold=60000 spring.datasource.hikari.register-mbeans=true
spring.datasource.hikari.leak-detection-threshold=5000
→spring.datasource.hikari.leak-detection-threshold=60000
に変更します。
runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
を削除する
Tomcat 起動時に spring-boot-properties-migrator がメッセージを出力していなかったので、build.gradle の dependencies block から runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
を削除します。削除後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
次回は。。。
Spring Framework の 5.1.4 がリリースされたので、まもなく Spring Boot の 2.0.8 が出るはずです。2.0.8 にバージョンアップしてから jar ファイルを作成→動作確認してから、最後に感想を書いて終わりにします。
履歴
2019/01/11
初版発行。