1
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?

Spring Boot 3 x Spring Security 6 でログイン画面を複数作成する際のSecurityFilterChainの書き方

Last updated at Posted at 2024-11-01

概要

ユーザー向け画面と管理画面の2つを作成したいケースがあると思います。
その際に、SecurityFilterChainの書き方で迷ったので備忘します。
SpringBoot3(SpringSecurity6)の記事が少なかった点と、
SpringBoot2の時と比べて差異があったため、記事にしました。

まとめ

  • SecurityFilterChainsecurityMatcher を利用する
  • Order の優先順位に注意する。

サンプルコード

ユーザー向け画面のSecurityFilterChain。

public class UserSecurityConfig {

    @Bean
    @Order(1)
    public SecurityFilterChain userSecurityFilterChain(HttpSecurity http) throws Exception {

        // URL認可
        http.securityMatcher("/user/**").authorizeHttpRequests((request) -> request

                // 常に許可
                .requestMatchers("/user/login").permitAll()
                .requestMatchers("/user/certification").permitAll()

                // ユーザー権限のみ許可
                .requestMatchers("/user/home").hasAuthority("USER")
        )

        // ログイン
        .formLogin(formLogin -> formLogin
                .loginPage("/user/login")
                .loginProcessingUrl("/user/certification")
                .defaultSuccessUrl("/user/home")
                .failureUrl("/user/login?error")
        )

        // ログアウト
        .logout(logout -> logout
                .logoutUrl("/user/logout")
                .logoutSuccessUrl("/user/login?logout=success")
                .deleteCookies("JSESSIONID")   // ログアウト後にCookie'JSESSIONID'を削除
                .invalidateHttpSession(true)   // ログアウト後にセッション無効化
        )

        return http.build();
    }
}

管理者向け画面のSecurityFilterChain。
Orderの値を変更して優先度を整理する。

public class AdminSecurityConfig {

    @Bean
    @Order(2)
    public SecurityFilterChain adminSecurityFilterChain(HttpSecurity http) throws Exception {

        // URL認可
        http.securityMatcher("/admin/**").authorizeHttpRequests((request) -> request

                // 常に許可
                .requestMatchers("/admin/login").permitAll()
                .requestMatchers("/admin/certification").permitAll()

                // 管理者権限のみ許可
                .requestMatchers("/admin/home").hasAuthority("ADMIN")
        )

        // ログイン
        .formLogin(formLogin -> formLogin
                .loginPage("/admin/login")
                .loginProcessingUrl("/admin/certification")
                .defaultSuccessUrl("/admin/home")
                .failureUrl("/admin/login?error")
        )

        // ログアウト
        .logout(logout -> logout
                .logoutUrl("/admin/logout")
                .logoutSuccessUrl("/admin/login?logout=success")
                .deleteCookies("JSESSIONID")   // ログアウト後にCookie'JSESSIONID'を削除
                .invalidateHttpSession(true)   // ログアウト後にセッション無効化
        )

        return http.build();
    }
}

ロールを付与するクラスを用意する。

@Component
public class AuthenticationSuccessEventListener {

    @EventListener
    public void onInteractiveAuthenticationSuccessEvent(InteractiveAuthenticationSuccessEvent event) {

        // 認証情報を取得
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetails principal = (UserDetails) authentication.getPrincipal();
        Object credentials = authentication.getCredentials();

        // 権限情報を設定
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        if (request.getServletPath().startsWith("/user")) {
            authorities.add(new SimpleGrantedAuthority("USER"));
        } else if (request.getServletPath().startsWith("/admin")) {
            authorities.add(new SimpleGrantedAuthority("ADMIN"));
        }

        // 認証情報を再設定
        Authentication newAuthentication = new UsernamePasswordAuthenticationToken(
                principal,
                credentials,
                authorities);
        SecurityContextHolder.getContext().setAuthentication(newAuthentication);
    }
}
1
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
1
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?