Webエンジニアのメモ帳

技術的な話を中心に書いています。

【Spring Security】ロールを使った認証の注意点

ロールを使った認証について

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です。

参考

Intro to Spring Security Expressions | Baeldung