AuthenticationSuccessHandler 설명
Custom SuccessHandler 구현
SecurityConfig 설정
GitHub 링크
Spring Security에서 인증이 성공했을 때 처리해야 할 작업을 정의하는 인터페이스입니다.
사용자가 성공적으로 인증되었을 때 실행할 코드를 정의할 수 있고, 주로 로그인 성공 후에 사용자를 특정 페이지로
리다이렉트하거나 로깅 등의 추가 작업을 수행할 때 사용됩니다.
CustomLoginSuccessHandler.java
package com.example.login.config;
import java.io.IOException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Component;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.RedirectStrategy;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@Component
public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler {
private RequestCache requestCache = new HttpSessionRequestCache();
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response
, FilterChain chain, Authentication authentication) throws IOException, ServletException {
AuthenticationSuccessHandler.super.onAuthenticationSuccess(request, response, chain, authentication);
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
System.out.println("==================");
System.out.println("로그인 성공");
System.out.println("==================");
SavedRequest savedRequest = requestCache.getRequest(request, response);
// 접근 권한 없는 경로로 접근해서 스프링 시큐리티가 인터셉트 후 로그인 페이지로 이동 한 경우
if (savedRequest != null) {
String targetUrl = savedRequest.getRedirectUrl();
redirectStrategy.sendRedirect(request, response, targetUrl);
}
// 로그인 버튼 눌러서 로그인 페이지로 이동 한 경우
else {
HttpSession session = request.getSession();
String prevPage = (String) session.getAttribute("prevPage");
redirectStrategy.sendRedirect(request, response, prevPage);
}
}
}
SecurityConfig.java
package com.example.login.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final CustomLoginSuccessHandler customLoginSuccessHandler;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// csrf token
http
.csrf((csrf) -> csrf.disable()); // 비활성화
// 인가
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/", "/login", "/loginProc", "/join", "/joinProc").permitAll() // 보안 검사 없이 접근을 허용
.requestMatchers("/member/**").hasAnyRole("ADMIN", "USER") // role - ADMIN, USER만 접근 허용
.requestMatchers("/admin").hasRole("ADMIN") // role - ADMIN만 접근 허용
.anyRequest().authenticated()
);
// Custom Login
http
.formLogin((form) -> form
.loginPage("/login")
.usernameParameter("loginId")
.passwordParameter("loginPwd")
.loginProcessingUrl("/loginProc")
.successHandler(customLoginSuccessHandler) // successHandler 추가
.permitAll()
);
// 세션 고정 보호
http
.sessionManagement((session) -> session
.sessionFixation((sessionFixation) -> sessionFixation
//.newSession() // 로그인 시 세션 신규 생성
.changeSessionId() // 로그인 시 세션은 그대로 두고 세션 아이디만 변경
)
);
// 로그아웃
http
.logout((logout) -> logout.logoutUrl("/logout")
.logoutSuccessUrl("/")
);
return http.build();
}
/**
* BCrypt 암호화
* @return
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}