ログインユーザのロールによって初期表示するページを変えたくなったのでその時のメモです。
例えば管理者と利用者でログイン後のページを変えたい場合などです。
環境
- 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();
}
以上です。
コメント