본문 바로가기
Spring/09. spring-security

Spirng Security 개념 및 동작 방식 정리

by 989898 2025. 3. 5.

Spring Security는 **인증(Authentication)과 권한 부여(Authorization)**를 담당하는 보안 프레임워크입니다.
우리가 기존 MVC 방식으로 직접 처리하던 로그인/로그아웃 로직을 자동으로 처리해 주기 때문에, 컨트롤러에서 로직을 구현할 필요가 없습니다.

🤔 Spring Security를 사용하면 왜 컨트롤러에서 데이터 처리를 안 해도 될까?

→ Spring Security가 내부적으로 필터(Filter) 기반의 인증 시스템을 제공하기 때문입니다.
→ 즉, 우리가 따로 데이터를 넘기지 않아도 SecurityContextHolder에 사용자 정보가 자동으로 저장되므로 Thymeleaf 같은 템플릿 엔진에서 바로 활용할 수 있습니다.

 

1. 기존 MVC 방식과 Spring Security의 차이

Spring Security가 없을 때와 있을 때의 로그인 처리 방식을 비교해 보겠습니다.

🔻 (1) 기존 Spring MVC 방식 (Spring Security ❌)

@PostMapping("/loginAction.do")
public String loginAction(LoginRequest loginRequest, BindingResult bindingResult, HttpSession session) {
    // 1️⃣ 사용자 입력 검증
    loginRequestValidator.validate(loginRequest, bindingResult);
    if (bindingResult.hasErrors()) {
        throw new UnauthorizedException();
    }

    // 2️⃣ 사용자 정보 확인 (DB 조회)
    LoginMember loginMember = memberService.doLogin(loginRequest.getMbEmail(), loginRequest.getMbPassword());
    if (Objects.isNull(loginMember)) {
        throw new UnauthorizedException();
    }

    // 3️⃣ 세션에 사용자 정보 저장
    session.setAttribute("loginMember", loginMember);
    session.setMaxInactiveInterval(60 * 30);

    return "redirect:/index.do";
}
  • 사용자가 입력한 Email과 Password를 받아서 검증을 수행
  • DB에서 해당 사용자가 존재하는지 확인
  • 로그인에 성공하면 세션(Session)에 사용자 정보 저장

🔹 이 코드의 문제점

  1. 모든 로직을 직접 구현해야 한다.
  2. 세션(Session)을 직접 관리해야 한다.
  3. 보안 취약점(비밀번호 암호화 처리 부족, CSRF 공격 등)을 개발자가 신경 써야 한다.

🔻 (2) Spring Security를 사용할 때 (Spring Security ✅)

http
    .formLogin(form -> form
        .loginPage("/auth/login.do")  // 로그인 페이지
        .loginProcessingUrl("/auth/loginAction.do")  // 로그인 요청 처리
        .defaultSuccessUrl("/index.do", false)  // 로그인 성공 후 이동할 페이지
        .usernameParameter("mbEmail")  // 이메일 필드 매핑
        .passwordParameter("mbPassword")  // 비밀번호 필드 매핑
        .permitAll()
    )
  • 로그인 처리를 직접 구현하지 않아도 Spring Security가 자동으로 처리
  • 로그인 성공 시, SecurityContextHolder에 자동으로 사용자 정보가 저장됨
  • Thymeleaf 같은 템플릿 엔진에서 별도의 데이터 전달 없이 사용자 정보 활용 가능

2. Spring Security가 내부적으로 어떻게 동작하는가?

Spring Security는 필터 기반(Security Filter Chain)의 구조로 동작합니다.


즉, 사용자의 요청이 들어오면 Spring Security의 필터들이 자동으로 인증/인가를 처리합니다.

🔹 Spring Security 인증 과정

1️⃣ 사용자가 로그인 요청 (/auth/loginAction.do)
2️⃣ Spring Security의 UsernamePasswordAuthenticationFilter가 요청을 가로챔
3️⃣ UserDetailsService가 DB에서 사용자 정보 조회 (loadUserByUsername())
4️⃣ 비밀번호 검증 (PasswordEncoder)
5️⃣ 인증 성공 시 SecurityContextHolder에 사용자 정보 저장
6️⃣ 이후 요청부터는 SecurityContextHolder에서 사용자 정보를 꺼내 사용 가능

🔥 결론: Spring Security가 자동으로 로그인/로그아웃 로직을 처리해 주므로, 컨트롤러에서 별도로 구현할 필요가 없음!

3. 기존 컨트롤러에서 데이터를 넘겨주던 방식과 Spring Security의 차이

🔹 (1) 기존 MVC 방식에서는 컨트롤러가 데이터를 직접 넘김

@GetMapping("/mypage")
public String myPage(Model model, HttpSession session) {
    LoginMember loginMember = (LoginMember) session.getAttribute("loginMember");
    if (loginMember == null) {
        return "redirect:/auth/login.do";
    }
    model.addAttribute("loginMember", loginMember);
    return "member/mypage";
}
  • session.getAttribute("loginMember")를 통해 로그인한 사용자 정보를 가져옴
  • 직접 Model 객체에 데이터를 추가해야 Thymeleaf에서 사용 가능

🔹 (2) Spring Security에서는 SecurityContextHolder에서 자동으로 가져옴

<ul sec:authorize="isAuthenticated()">
    <li>
        <span sec:authentication="principal.username"></span>  <!-- 로그인한 사용자 이메일 출력 -->
        <ul th:each="item : ${#authentication.authorities}">
            <li th:text="${item}"></li>  <!-- 사용자 권한 출력 -->
        </ul>
    </li>
</ul>
  • sec:authentication="principal.username" → 로그인한 사용자의 이메일을 자동으로 가져옴
  • #authentication.authorities → 사용자의 권한(Role) 정보를 가져옴
  • 즉, 컨트롤러에서 데이터를 넘겨주지 않아도 자동으로 가져올 수 있음!

🎯 결론: Spring Security가 SecurityContextHolder에 사용자 정보를 자동으로 저장하므로, 컨트롤러에서 따로 데이터를 넘길 필요가 없음!

4. Spring Security를 적용한 로그인/로그아웃 정리

🔹 로그인

동작 기존 방식 (MVC) Spring Security 적용
입력값 검증 직접 Validator 구현 자동 처리
사용자 조회 memberService.doLogin() UserDetailsService에서 자동 조회
비밀번호 검증 직접 비교 PasswordEncoder.matches()로 자동 검증
세션 저장 session.setAttribute() SecurityContextHolder에 자동 저장
로그인 후 이동 return "redirect:/index.do" defaultSuccessUrl()로 설정

🔹 로그아웃

동작 기존 방식 (MVC) Spring Security 적용
로그아웃 처리 session.invalidate() logoutUrl("/auth/logoutAction.do") 설정
로그아웃 후 이동 return "redirect:/index.do" logoutSuccessUrl() 설정

5. 정리: 왜 Spring Security를 쓰는가?

1️⃣ 로그인/로그아웃 로직을 직접 구현할 필요가 없음
2️⃣ SecurityContextHolder를 활용해 컨트롤러에서 데이터를 넘기지 않아도 됨
3️⃣ 비밀번호 암호화, 세션 관리, 인증/권한 부여를 자동 처리
4️⃣ Spring Security의 Thymeleaf 확장을 사용해 간단한 코드로 사용자 정보 활용 가능


🎯 한 줄 요약

💡 Spring Security는 인증 및 권한 관리를 자동으로 처리하기 때문에,
별도의 컨트롤러 구현 없이도 로그인, 로그아웃, 사용자 정보 조회가 가능하다! 🚀