목차

AuthenticationSuccessHandler 설명

Custom SuccessHandler 구현

SecurityConfig 설정

GitHub 링크


AuthenticationSuccessHandler 설명

Spring Security에서 인증이 성공했을 때 처리해야 할 작업을 정의하는 인터페이스입니다.

사용자가 성공적으로 인증되었을 때 실행할 코드를 정의할 수 있고, 주로 로그인 성공 후에 사용자를 특정 페이지로

리다이렉트하거나 로깅 등의 추가 작업을 수행할 때 사용됩니다.



Custom SuccessHandler 구현

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 설정

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();
    }
  
}


GitHub 링크

전체 소스 다운로드

©2024, DevDream