0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Spring Securityのanonymous

Posted at

公式ドキュメントのAnonymous Authenticationにあるとおり、セキュリティにおいては許可を与えたもの以外はすべて拒否がベターである。spring-securityをwebで使う場合はfilter chainで実装される。このとき、認証ユーザはfilter chainを通す一方、未認証ユーザはバイパスすると、未認証ユーザだけ特殊扱いになり不便な場合もある。そこでspring-securityはanonymous認証ユーザを用意している。実質的には未認証な認証ユーザという位置づけになる。

以降のサンプルコードはspring-security 6がベース。build.gradleは以下の通り。

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.0.3'
	id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

両者の分かりやすい挙動の違いはcontrollerにおいて認証オブジェクトであるAuthenticationの取得とその型。参考:公式ドキュメントのGetting Anonymous Authentications with Spring MVC

  @GetMapping("/sample")
  String sample(Authentication authentication, @CurrentSecurityContext SecurityContext context) {
    ...

注意点としては、anonymousだとAuthentication引数はnullになる。これを避けたければ@CurrentSecurityContextを使う。

状態 認証済み 未認証(anonymous)
Authentication UsernamePasswordAuthenticationToken null
@CurrentSecurityContext UsernamePasswordAuthenticationToken AnonymousAuthenticationToken

またanonymousはROLE_ANONYMOUSという認可をデフォルトで持つのでこれでアクセス制御が出来る。たとえば、以下にすると/anonは未認証ユーザのみアクセス可能になる。参考:https://www.tenohira.xyz/tech/spring-anonymous-only-access/

@Configuration
@EnableWebSecurity
public class SecurityConfig {
  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.formLogin(login -> login
        // 省略
    ).authorizeHttpRequests(authz -> authz
        .requestMatchers("/anon").anonymous()
        //.requestMatchers("/anon").hasRole("ANONYMOUS") // 上と同じ意味
        .anyRequest().authenticated()
    );
    return http.build();
  }

thymeleafでanonymousかどうかで何等かの表示の出し分けをするのは以下の通り。より細かい使い方については https://kagamihoge.hatenablog.com/entry/2019/11/12/195357 を参照。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:th="https://www.thymeleaf.org"
  xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>anonymous sample</title>
</head>
<body>
		<div sec:authorize="isAnonymous()">
		  ANONYMOUSです。
		</div>
		<div sec:authorize="hasRole('ANONYMOUS')">
		  ANONYMOUSです。
		</div>
</body>
</html>

anonymousの認可をデフォルトのROLE_ANONYMOUSから変更したり、principalを変更したり、anonymous認証の無効化は以下のようにする。

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http. 
     // 省略
    ).anonymous((anon) -> anon
        .authorities("ROLE_HOGE", "ROLE_FOO")
        .principal("アノニマス")
        // .disable() // 無効化
    );
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?