はじめに
久々に個人開発をしようと思い SpringSecurity で認証機能を実装しようとしたところ、SpringSecurity5.7以降
Configクラスの記述方法に大きな変更が加えられていることを知りました。そこで今回は 最新版である6.0.1
で認証機能を実装することとしましたが、作業中にいくつか躓く場面があったため、復習を兼ねて記事として投稿してみます。
ちなみに私は 公式ドキュメント を参考にしながら実装しました。
今回は時間がないためConfigクラスの変更点についてのみ触れ、メソッドチェーンそれぞれがどういった役割をしているか等は割愛させていただきます。時間がある際に実際にDBから取得したユーザ情報でログインといった通しの実装について記事を書きたいと思っています。
開発環境
- Java17
- postgreSQL 14.3
- SpringBoot 3.0.2
- SpringSecurity 6.0.1
- Gradle
- Thymeleaf
各種設定など
依存関係の定義
// 一部のみ記載
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
DB接続情報の設定
今回はログイン機能のみのため不要ですが、
postgresのドライバを入れている都合上記述しないとエラーを吐くので....
# postgres 接続設定
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=test
spring.datasource.password=test
Configクラスの実装
この記事のメインになります。
これまでは WebSecurityConfigureAdapter
を継承した実装をしていましたが、SecurityFilterChain
をBean定義できるようになったため下記のような記述が可能になりました。メソッドチェーンの書き方などは以前とかなり似通っていますが、細かい変更点があるので少しだけ自分が理解したことを書かせていただこうと思います。
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.formLogin(login -> login
.loginPage("/login")
.loginProcessingUrl("/login")
.usernameParameter("username") // デフォルトのため実際には記述不要
.passwordParameter("password") // デフォルトのため実際には記述不要
.defaultSuccessUrl("/")
.failureUrl("/login?error")
.permitAll()
).logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
).authorizeHttpRequests(authz -> authz
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.requestMatchers("/login").permitAll()
.requestMatchers("/regist").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
では、新しい書き方をしている箇所についてのみ触れていきます。
■ .authorizeHttpRequests()
以前は .authorizeRequests()
を使用していましたが、非推奨となっていたため変更。(参考)
おそらくですが .authorizeRequests()
はそのうち削除されるようです。
■ .requestMatchers()
SpringSecurity6.0で削除された .antMatchers()
.mvcMatchers()
の代替です。
また requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
の部分ですが、この一文でHTMLやCSSなどの静的リソースをSpringSecurityの保護対象外としています。
.requestMatchers("/css/**").permitAll()
のように各静的リソースのパスを指定する方法もありますが、
SpringBootを使用する場合はこの書き方で一律保護対象外に設定できるので便利です。
■ PasswordEncoder()
こちらも若干記述を変更しています。
これまでは下記のように BCrypt によるパスワードのハッシュ化を行っていましたが、
どうやら将来的な移行の容易さなどを考慮して、Bcrypt
のみではなく noop
や sha256
など、
他のエンコード方式も包括して対応できるようにするためこの書き方が推奨されるようです。
勿論、Bcryptでも正常に動作はします。詳しいことは 公式ドキュメントをご覧いただければと思います。
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
終わりに
非常に簡潔な記事で申し訳ありませんが、重要な変更点はこのあたりかと思います。
間違いなどがございましたら是非、指摘をお願いいたします。
最近全く認証機能を触る機会がなかったため、こういった変更があったこと自体知りませんでした。
他にも色々な箇所で無自覚に非推奨となってしまったコーディングを続けていると思いますので、
敏感に最新版へアップデートする癖を付けていきたいと思います。