inblog logo
|
harimmon
    심화 과정

    [심화] 12. Spring Security 세션 인증

    백하림's avatar
    백하림
    Jul 25, 2025
    [심화] 12. Spring Security 세션 인증
    Contents
    1. 스프링 시큐리티란?2. 스프링 시큐리티 필터 체인3. 프록시 패턴과 Spring Security4. 인증과 인가 로직 (Form Login 흐름)5. 주요 필터 종류 정리6. FormLogin vs HTTP Basic7. JWT 기반 로그인 (간단 요약)🔗 참고 자료✅ SecurityContextHolder란?🧠 작동 원리 요약🔐 내부 구조 요약📦 왜 ThreadLocal 기반인가?✅ 로그인 후 인증 객체 접근 예시📌 한 줄 요약🔄 그림으로 전체 요청 흐름 요약🌐 전체 요청 처리 흐름 요약 (Spring MVC + Spring Security)

    SecurityConfig

    package com.metacoding.securityapp1.core; 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.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.SecurityFilterChain; // 예: localhost:8080/user/asdasd, localhost:8080/user/join-form @Configuration // 이 클래스는 스프링 설정 클래스임을 명시 (빈 등록 용도) public class SecurityConfig { // 비밀번호 암호화를 위한 단방향 해시 함수 (회원가입/로그인 시 사용) @Bean public BCryptPasswordEncoder encodePwd() { return new BCryptPasswordEncoder(); } @Bean // SecurityFilterChain을 빈으로 등록하여 보안 설정을 적용함 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // H2 Console은 iframe으로 동작하므로, 기본적으로 막혀있는 iframe을 sameOrigin으로 허용함 http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.sameOrigin())); // CSRF 보호 기능 비활성화 (개발/테스트용. 실서비스에서는 활성화 권장) http.csrf(configure -> configure.disable()); // 폼 로그인 방식 설정 http.formLogin(form -> form .loginPage("/login-form") // 로그인 페이지 URL (GET). 사용자가 인증 안 됐을 때 여기로 이동함 .loginProcessingUrl("/login") // 로그인 처리 URL (POST). 컨트롤러 없이도 Spring Security가 자동으로 인증 처리 .defaultSuccessUrl("/main") // 로그인 성공 후 이동할 기본 페이지 ); // 요청 URL별 인가 설정 http.authorizeHttpRequests( authorize -> authorize .requestMatchers("/main").authenticated() // 로그인만 되어 있으면 접근 가능 .requestMatchers("/user/**").hasRole("USER") // USER 권한 있어야 접근 가능 .requestMatchers("/admin/**").hasRole("ADMIN") // ADMIN 권한 있어야 접근 가능 .anyRequest().permitAll() // 그 외 모든 요청은 인증 없이 접근 허용 ); return http.build(); // 구성된 보안 필터 체인 객체를 반환 } }
    🔥
    SecurityFilterChain을 재정의했다 → Spring Security의 기본 필터 체인을 작성한 코드로 덮어쓴 것이고, → HttpSecurity를 사용해서 필터의 **행동 방식(인증, 인가, 로그인 방식 등)**을 하나하나 세밀하게 조정한 것임.

    1. 스프링 시큐리티란?

    Spring Security는 스프링 기반 웹 애플리케이션의 인증(Authentication)과 인가(Authorization)를 처리하는 보안 프레임워크다.

    주요 기능:

    • 로그인(인증) 처리
    • 권한(인가) 체크
    • 세션 관리
    • CSRF/XSS 방어
    • 다양한 인증방식 지원: Form Login, HTTP Basic, JWT, OAuth2 등

    🔐 인증 vs 인가

    개념
    설명
    인증 (Authentication)
    "너 누구야?" → 로그인 검증
    인가 (Authorization)
    "이 기능 써도 돼?" → 권한 체크

    2. 스프링 시큐리티 필터 체인

    요청이 들어오면 DispatcherServlet 이전에 Spring Security의 필터 체인이 먼저 실행됨.
    (실제로는 서블릿 필터 다음에 DelegatingFilterProxy가 SecurityFilterChain을 호출함)

    🔄 필터 체인 구조

    [사용자 요청] ↓ [서블릿 필터] ↓ [DelegatingFilterProxy] ↓ [SecurityFilterChain] ├─ UsernamePasswordAuthenticationFilter ├─ BasicAuthenticationFilter ├─ ExceptionTranslationFilter ├─ FilterSecurityInterceptor └─ ...
    필터는 순차적으로 실행되며, 인증/인가 처리, 예외 처리 등을 담당함.

    3. 프록시 패턴과 Spring Security

    Spring Security는 내부적으로 프록시 패턴을 활용함.
    → UserDetails, Authentication, SecurityContext 등을 가짜로 감싸서 동작을 위임함
    예시:
    SecurityContextHolder.getContext().getAuthentication()
    → 실제 로그인된 사용자 정보를 꺼내는 방식도 프록시 기반으로 동작
    참고 강의: 프록시 패턴 설명 유튜브

    4. 인증과 인가 로직 (Form Login 흐름)

    🔑 Form Login 흐름 요약

    scss 복사편집 [POST /login 요청] ↓ [UsernamePasswordAuthenticationFilter] ↓ (성공 시) [SecurityContextHolder.setAuthentication()] ↓ [세션 저장]
    • 인증 실패 시 → 다시 /login-form으로 이동
    • 인증 성공 시 → Authentication 객체가 세션에 저장됨
    폼 로그인을 사용하는 경우 UsernamePasswordAuthenticationFilter가 동작함
    HTTP Basic 인증을 사용할 경우 BasicAuthenticationFilter가 동작 (동시에 둘 다 사용 불가)

    5. 주요 필터 종류 정리

    필터명
    언제 작동?
    무엇을 하는가?
    UsernamePasswordAuthenticationFilter
    로그인(form login) 요청 (/login 등)일 때 작동
    사용자의 아이디/비밀번호를 추출하여 AuthenticationManager를 통해 인증 수행. 인증 성공 시 SecurityContextHolder에 저장
    BasicAuthenticationFilter
    요청 헤더에 Authorization: Basic ...이 있을 때 작동
    Base64로 인코딩된 사용자 정보를 디코딩하고 인증 수행
    ExceptionTranslationFilter
    아래의 필터 중 인증/인가 예외가 발생했을 때 작동
    인증 안된 사용자는 로그인 페이지로 redirect, 인가 실패는 403 오류 반환
    SecurityContextHolderAwareRequestFilter
    매 요청마다 작동
    HttpServletRequest를 시큐리티 aware 객체로 래핑해, request.isUserInRole() 등 사용 가능하게 함
    FilterSecurityInterceptor
    컨트롤러에 진입하기 직전
    인증된 사용자가 해당 자원에 접근할 권한이 있는지 최종 확인 (인가 핵심)
    LogoutFilter
    /logout 요청일 때 작동
    세션 종료, SecurityContext 초기화, 로그아웃 후 redirect 수행
    SessionManagementFilter
    로그인 성공 시 또는 세션 체크 시점
    세션 중복 로그인 제한, 세션 만료 처리 등 관리

    6. FormLogin vs HTTP Basic

    Form Login 구성 예시

    java 복사편집 http.formLogin(form -> form .loginPage("/login-form") .loginProcessingUrl("/login") .defaultSuccessUrl("/main")
    → 내부적으로 동작:
    1. /login-form: 로그인 페이지 2. /login (POST): 시큐리티가 가로채서 로그인 처리 3. 성공 시: /main 이동

    HTTP Basic 구성 예시

    http.httpBasic(); // 브라우저에서 ID/PW 팝업 뜸
    → 이 경우에는 BasicAuthenticationFilter가 동작하고 UsernamePasswordAuthenticationFilter는 동작 안함

    7. JWT 기반 로그인 (간단 요약)

    JWT를 사용할 경우 세션을 사용하지 않고, 인증 정보를 직접 SecurityContext에 저장함

    강제로 인증 객체 삽입하기

    User user = User.builder().id(id).role(role).build(); MyUserDetails myUserDetails = new MyUserDetails(user); Authentication authentication = new UsernamePasswordAuthenticationToken( myUserDetails, myUserDetails.getPassword(), myUserDetails.getAuthorities() ); SecurityContextHolder.getContext().setAuthentication(authentication);
    → 이 코드를 통해 세션 없이도 인증 상태를 수동으로 주입 가능함

    🔗 참고 자료

    • GitHub (SSR 방식): https://github.com/codingspecialist/Springboot-Security/tree/ssr-topic
    • GitHub (CSR/JWT 방식): https://github.com/codingspecialist/Springboot-Security/tree/csr-topic
    • 공식문서: https://docs.spring.io/spring-security/reference/servlet/architecture.html
    • 토리맘 블로그: https://godekdls.github.io/Spring%20Security/servletsecuritythebigpicture/

    ✅ SecurityContextHolder란?

    한 줄 정의:

    인증 객체(Authentication)를 저장하고 관리하는 ThreadLocal 기반의 보안 컨텍스트 저장소

    🧠 작동 원리 요약

    인증 흐름 중 이 위치에서 등장:

    1. 로그인 요청 (POST /login) ↓ 2. UsernamePasswordAuthenticationFilter ↓ 3. 로그인 성공 시 Authentication 객체 생성 ↓ ✅ SecurityContextHolder.getContext().setAuthentication(authentication) ↓ 4. SecurityContext가 세션에 저장됨
    • 이렇게 저장된 Authentication은 이후 모든 요청에서 다시 꺼내서 사용됨
    • 꺼내는 방식:
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    → 현재 로그인한 유저의 정보를 여기서 얻을 수 있음.

    🔐 내부 구조 요약

    SecurityContextHolder → SecurityContext (보안 컨텍스트) → Authentication (인증 정보) → Principal (사용자 정보) → Credentials (비밀번호) → Authorities (권한 목록)

    📦 왜 ThreadLocal 기반인가?

    • 사용자 요청은 스레드마다 독립적으로 처리됨
    • 그래서 로그인 정보(인증 정보)를 ThreadLocal로 담아두면
      • 하나의 사용자 요청이 처리되는 동안 안전하게 인증 정보를 사용할 수 있음

    ✅ 로그인 후 인증 객체 접근 예시

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String username = authentication.getName(); // 로그인한 username Collection<? extends GrantedAuthority> roles = authentication.getAuthorities();

    📌 한 줄 요약

    이름
    역할
    비고
    SecurityContextHolder
    인증 정보를 담는 글로벌 저장소
    ThreadLocal 기반
    SecurityContext
    실제 인증 정보(Authentication)를 담고 있음
    세션과 연결됨
    Authentication
    로그인 사용자 정보, 권한 등을 포함함
    인증 여부 판단 기준

    🔄 그림으로 전체 요청 흐름 요약

    [POST /login] ↓ [UsernamePasswordAuthenticationFilter] ↓ [Authentication 생성 성공] ↓ [SecurityContextHolder.setContext(인증 정보)] ↓ [세션에 SecurityContext 저장] ↓ [다음 요청부터 SecurityContextHolder.getContext()로 인증 정보 꺼냄]

    🌐 전체 요청 처리 흐름 요약 (Spring MVC + Spring Security)

    [사용자 요청 (URL 입력)] ↓ [WAS (Tomcat)] ↓ [Spring Security Filter Chain] ← 인증/인가 필터들 ↓ [DispatcherServlet (DS)] ← 요청의 핵심 분기 처리 ↓ [HandlerMapping] ← 어떤 Controller 메서드가 호출될지 결정 ↓ [Controller] ← 요청 처리 시작 ↓ [Service] ← 비즈니스 로직 처리 ↓ [Repository] ← DB 연산 (JPA, MyBatis 등) ↓ [Database] ← 실제 데이터 저장/조회 ↓ [응답 생성 → JSON / View 등] ↓ [DispatcherServlet] ↓ [WAS → 사용자에게 HTTP 응답 전송]

    BasicAuthentication

    🔥
    매 요청(Request)마다 클라이언트가 아이디/비밀번호를 Authorization 헤더에 실어 보내고
    서버는 그걸 디코딩해서 인증하는 방식임.
    Share article
    Contents
    1. 스프링 시큐리티란?2. 스프링 시큐리티 필터 체인3. 프록시 패턴과 Spring Security4. 인증과 인가 로직 (Form Login 흐름)5. 주요 필터 종류 정리6. FormLogin vs HTTP Basic7. JWT 기반 로그인 (간단 요약)🔗 참고 자료✅ SecurityContextHolder란?🧠 작동 원리 요약🔐 내부 구조 요약📦 왜 ThreadLocal 기반인가?✅ 로그인 후 인증 객체 접근 예시📌 한 줄 요약🔄 그림으로 전체 요청 흐름 요약🌐 전체 요청 처리 흐름 요약 (Spring MVC + Spring Security)

    harimmon

    RSS·Powered by Inblog