Spring Security を使った認可の実装例
認可の実装には、① HTTPのリクエストを制限する ② Javaメソッドの実行を制限する ③ 動線を非表示にする の3つの方法があると解説しました。
このレクチャーでは、それぞれの方法について Spring での実装例を見ていきましょう。
目次
HTTP リクエストを制限する方法
HTTP リクエストを制限する方法は HttpSecurity クラスへの設定によって実現します。
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(antMatcher("/admin/**")).hasAuthority("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}
.requestMatchers
から始まる行のように、リクエストを制限したいパスと権限を指定します。
この例では、ADMIN
権限を持つログインユーザーだけが /admin
とその配下のパスにアクセスできるように記述しています。
Java メソッドの実行を制限する方法
Java メソッドの実行を権限によって制御するには、@PreAuthorize
アノテーションを使います。
まず、このアノテーションを有効にするため、@EnableMethodSecurity
アノテーションを付けたクラスを宣言します。
@EnableMethodSecurity
public class MethodSecurityConfig {
}
MethodSecurityConfig
クラスは、@EnableMethodSecurity
アノテーションを宣言するためだけのクラスで、中身は空です。
@EnableMethodSecurity
によって @PreAuthorize
が有効にできたら、権限によって実行を制御したいメソッドに @PreAuthorize
アノテーションを付けます。
@PreAuthorize
アノテーションの引数にはアクエスを許可する権限を指定します。
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
@PreAuthorize("hasAuthority('ADMIN')")
public List<User> findAll() {
return userRepository.findAll();
}
@PreAuthorize("hasAuthority('ADMIN')")
public void create(String username, String password, String authority) {
var encodedPassword = passwordEncoder.encode(password);
userRepository.insert(username, encodedPassword, authority);
}
}
この例では、UserService
クラスの findAll
メソッドと create
メソッドは、ADMIN
権限を持つユーザーのみがアクセスできるように制限しています。
動線を非表示にする方法
動線を非表示にするには、Thymeleaf の authorize
という記法を使います。
はじめに、build.gradle
の dependencies セクションに thymeleaf-extras-springsecurity6
の記述を追加します。
(使用している Spring Security のバージョンが 5 の場合は、thymeleaf-extras-springsecurity5
と書きます)
dependencies {
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
}
thymeleaf-extras-springsecurity6
を依存関係に追加したら、テンプレートファイルに認可に関する記述を追加します。
<!DOCTYPE html>
<html lang="ja"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6"
>
<head>
<title>トップページ</title>
</head>
<body>
<a sec:authorize="hasAuthority('ADMIN')" th:href="@{/admin}">管理者メニュー</a>
</body>
</html>
xmlns:sec
から始まる行にあるように、sec
というプレフィクスで thymeleaf-extras-springsecurity6
の機能を使用できるように宣言します。
その上で sec:authorize="hasAuthority('ADMIN')
と書くと、ADMIN
ロールを持つユーザーに対してだけ sec:authorize
が記述された要素が表示されるようになります。
この例では、/admin
に遷移するための「管理者メニュー」というリンクは、ADMIN
ロールを持つユーザーにだけ表示するように制御しています。
まとめ
このレクチャーでは、Spring Security を使った認可の実装方法を紹介しました。 認可の実装方法それぞれを実現するための方法は次のとおりです:
- HTTPのリクエストを制限する:
HttpSecurity
に対してrequestMatchers
を設定する - Javaメソッドの実行を制限する:
@PreAuthorize
を付与する - 動線を非表示にする:
sec:authorize
を使う