本ブログはアフィリエイト広告を利用しています。

Spring Security ログイン後にロールによって初期表示ページを変更する

ログインユーザのロールによって初期表示するページを変えたくなったのでその時のメモです。
例えば管理者と利用者でログイン後のページを変えたい場合などです。

環境

  • Spring Security 6.1.3
  • JDK 20

実装

コード自体は割と簡単です。
AuthenticationSuccessHandlerをimplementsで実装し、認証成功後にロールによってリダイレクト先を変更していきます。
ROLE_XXXXの場合は https://xxxxyyyyzzzz.com/xxxxTopPage 、それ以外のロールは https://xxxxyyyyzzzz.com/otherTopPage にアクセスするようにしています。

import java.io.IOException;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        String targetUrl = determineTargetUrl(authentication);
        redirectStrategy.sendRedirect(request, response, targetUrl);
    }

    protected String determineTargetUrl(Authentication authentication) {
        String url = "";

        // ユーザーのロールに基づいてリダイレクト先のURLを設定
        for (GrantedAuthority authority : authentication.getAuthorities()) {
            String roleName = authority.getAuthority();

            if (roleName.equals("ROLE_XXXX")) {
                url = "/xxxxTopPage";
                break;
            } else {
                url = "/otherTopPage";
                break;
            }
        }

        return url;
    }
}

次に、作成したクラスをSpring側に教えてあげる設定を行います。
formLoginにsuccessHandler(new CustomAuthenticationSuccessHandler())を設定します。
もしdefaultSuccessUrl(“/”)とか設定していた場合は不要なので削除しましょう。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authz -> authz
                // 省略
                )
        .exceptionHandling(e -> e
                .accessDeniedHandler(new AccessDeniedHandlerImpl() {
                    @Override
                    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
                        response.sendError(HttpServletResponse.SC_FORBIDDEN);
                    }
                }))
        .formLogin(login -> login
                .loginProcessingUrl("/login")
                .loginPage("/login")
                .successHandler(new CustomAuthenticationSuccessHandler())
                .failureUrl("/login?error")
                .permitAll())
        .logout(logout -> logout
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login")
                .permitAll())
        ;

        return http.build();
    }

以上です。

コメント

タイトルとURLをコピーしました