ロールを使った認証について
Springを使った開発では、Spring Securityを使えば認証・認可の機能が実装できます。
例えばフォームを使ったログインなどであれば、以下の記事で説明しているように簡単に実装できます。
http://lavapies9.com/2021/03/03/2021-03-03-221053/
上記のサンプルではユーザー名とパスワードを使って認証をしているだけですが、ユーザーにロールを持たせ、ロールに応じてアクセスできるページを決めることなどができます。
ユーザーにロールを持たせる方法は、こちらのサイトなどが参考になります。
Spring Securityを使った認証・認可ではUserDetailsService
インターフェースを継承するクラスの実装が必須となりますが、ロールの設定はここで記述することができます。
ロールを使った認証の注意点
この記事の本題はここからです。
ロールによってアクセス可能なパスを変えるには、WebSecurityConfigurerAdapterという抽象クラスを継承したクラスを実装し、configure()
メソッドをオーバーライドします。
たとえば、/admin/
以下のパスにはADMIN
ロールを持つ人だけがアクセスでき、それ以外のパスにはADMIN
ロールを持つ人とUSER
ロールを持つ人がアクセスできるようにする場合、以下のように記述します。
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("**").hasAnyRole("ADMIN","USER") // 以下設定が並ぶ }
このメソッドを使おうとして、いくつかハマった点があったのでメモです。
1. ロールに対してではなく、パスに対して設定を行う。
設定が複雑だと
antMatchers("パス").hasAnyRole("ロール")
という文章が大量に並ぶことになりますが、「パス」に対して「アクセスできるロール」を記述します。
私は「ロール」に対して「アクセス可能なページ」を記述するような書き方をしてしまい、意図した挙動になりませんでした。
2. /**の扱いについて
管理画面のトップページが/admin
というパスだとした場合、上に書いた例では/admin
には誰もアクセスできません。
/admin
は/admin/**
にマッチしないからです。この場合は、
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin", "/admin/**").hasRole("ADMIN") .antMatchers("**").hasAnyRole("ADMIN","USER") // 以下設定が並ぶ }
と記述する必要があります。
3. 範囲が広いパスを下の行に記述する
もし↓のように書いた場合は、/admin/**
にUSER
ロールのユーザーもアクセスできてしまいます。
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("**").hasAnyRole("ADMIN","USER") .antMatchers("/admin/**").hasRole("ADMIN") // 以下設定が並ぶ }
下の行に書いたパスに上の行に書いたパスが含まれるのはOKですが、逆はNGです。