Spring Security 사용하기

윤한영·2025년 6월 13일
1
post-thumbnail

프론트 부분의 구조나 디자인에 대한 내용은 각자 원하시는대로 하시면 될 것 같고,
저는 디자인은 GPT, V0와 같은 AI 툴들을 사용해서 만들었습니다. (디자인은 자신이..😅)

UI가 필요하신 분들은 [로그인 기능 구현] 여기 깃 코드 사용하시면 될 것 같습니다.

Spring Security 공부를 위해 로그인 기능을 구현하는 것이기에 프론트보다는 백엔드에 초점을 맞추어 작성 하도록 하겠습니다.

프로젝트 세팅을 하지 않으신 분들은 [React+SpringBoot 프로젝트 생성하기] 블로그를 먼저 보고 와주시길 바랍니다.

[ Spring Security란? ]

Security를 사용하기 전에 간략하게 무엇인지를 알아보자면
Spring Security는 Spring 기반의 애플리케이션의 보안(인증과 권한, 인가 등)을 담당하는 스프링 하위 프레임워크이다.
Spring Security는 '인증'과 '권한'에 대한 부분을 Filter 흐름에 따라 처리하고 있다. Filter는 Dispatcher Servlet으로 가기 전에 적용되므로 가장 먼저 URL 요청을 받는다.

Spring Security는 보안과 관련해서 체계적으로 많은 옵션을 제공해주기 때문에 개발자 입장에서는 일일이 보안관련 로직을 작성하지 않아도 된다는 장점이 있다.

  • 인증(Authentication): 해당 사용자가 본인이 맞는지를 확인하는 절차
  • 인가(Authorization): 인증된 사용자가 요청한 자원에 접근 가능한지를 결정하는 절차 

참고


스프링은 버전에 따라 구현 방식이 조금씩 변경되는데 시큐리티의 경우 특히 세부 버전별로 구현 방법이 많이 다르기 때문에 버전마다 구현 특징을 확인해야 한다고 합니다.
[참고], [Spring Security GitHub Releases Note]



1️⃣ Spring Security 사용하기 (의존성 추가)

Security를 사용하기 위해서는 build.gradle 파일에 의존성을 먼저 추가하여야 합니다.

dependencies {
	...
	implementation 'org.springframework.boot:spring-boot-starter-security'	// Spring Security
    ...
}

2️⃣ Config 클래스 설정

의존성을 추가하면 Spring Security를 사용할 수 있습니다.
Security를 사용하기 위한 SecurityConfig 클래스를 생성합니다.

사용하는 메서드명(ex: filterChain)은 원하시는 이름으로 정하고
리턴 타입은 SecurityFilterChain 으로 하셔야 합니다.

  • @Configuration

    • 스프링 프레임워크에서 사용되는 어노테이션 중 하나로, 해당 클래스를 스프링의 설정 클래스로 지정하는 역할을 합니다.
    • 해당 어노테이션이 적용된 클래스는 스프링의 설정 정보를 포함하고 있는 클래스로 간주됩니다.
  • @EnableWebSecurity

    • Spring Security를 사용하여 웹 보안을 구성할 때 사용하는 어노테이션입니다. 이 어노테이션을 사용하면 Spring Security와 관련된 구성을 할 수 있습니다.
    • Spring Security의 기능을 활성화하고, 주로 WebSecurityConfigurerAdapter 클래스를 상속받아 사용합니다.
      /* 과거에는 이렇게 구현하였지만 */
      @Configuration
      @EnableWebSecurity
      public class SecurityConfig extends WebSecurityConfigurerAdapter {
      	...
      }
      /* 
      Spring Boot 3.0 이상
      Spring Security 6 이상에서는 WebSecurityConfigurerAdapter는 사용 불가 */
      @Configuration
      @EnableWebSecurity
      public class SecurityConfig {
      	...
      }
    • 해당 어노테이션을 사용하면 아래와 같은 작업을 수행할 수 있습니다.
      • HttpSecurity 객체를 사용하여 HTTP 요청에 대한 보안 구성을 설정할 수 있습니다.
      • WebSecurityConfigurerAdapter 클래스를 상속받은 설정 클래스를 등록할 수 있습니다.
    • [@EnabledWebSecurity 파헤치기] → 관련된 내용 공부해서 추후에 정리해 보겠습니다~!
  • HttpSecurity http
    • Spring Security 의 HTTP 보안 설정을 구성하기 위한 클래스입니다.
    • 주로 URL 패턴에 따라 접근을 제한하거나, 인증 및 인가에 대한 규칙을 설정합니다.
    • WebSecurityConfigurerAdapter 를 확장하여 사용하며, configure(HttpSecurity http) 메소드를 오버라이드하여 필요한 정보를 추가합니다.
    • http 에서 사용하는 메서드들은 람다 형태로 사용하시면 됩니다.
    • 참고


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		// 인가
        http
                .authorizeHttpRequests((auth) -> auth
                        .requestMatchers("/", "/login").permitAll()
                        .requestMatchers("/getUserInfo").hasRole("ADMIN")
                        .anyRequest().authenticated()
                );
        // 인증     
        http
                .formLogin((auth) -> auth.loginPage("/login")       // 권한이 없는 admin과 같은 경로로 사용자가 요청했을 때 오류 페이지가 아닌 작성한 "경로"로 Spring Security가 리다이랙트 시켜줌
                        .loginProcessingUrl("/loginProc")           // 해당 경로로 요청이 들어오면 Security가 로그인 처리를 진행
                        .defaultSuccessUrl("/login", true)
                        .permitAll()                                // 로그인 처리를 한다는게 permitAll() 권한을 준다는 것 같음
                );

        http
                .csrf((auth) -> auth.disable());                    // POST방식으로 요청을 진행할 때 CSRF(사이트 위변조 방지 설정) 토큰을 보내야 로그인 처리를 가능하게 함, 이러한 설정은 Spring Security에서 설정되어 있음
                                                                    // 개발환경에서는 토큰을 사용하는 것이 불편하므로 disable 처리, 추후에 inable 처리하도록 수정

        return http.build();
    }
}

코드에 대한 설명을 하자면
  • requestMatchers(경로): "경로"에 대한 권한을 설정할 수 있다.
  • permitAll(): 모든 사용자에게 접근 가능하도록 설정
  • hasRole(권한): "권한"이 있는 사용자만이 requestMatchers(경로)에 설정된 경로에 접근할 수 있다.
  • hasAnyRole(권한1, 권한2, ...): 여러 "권한"에 대해 접근을 제어할 수 있다.
  • anyRequest(): 위에서 처리하지 못한 나머지 경로에 대한 권한 제어를 처리할 수 있음.
  • authenticated(): 로그인한 사용자만이 접근할 수 있도록
    denyAll(): 모든 사용자의 접근을 제한함

requestMatchers()를 이용해 경로에 대한 접근을 제한할 때 순서가 중요하다. 많은 권한에 대한 제한은 가장 마지막에 작성하는 것이 올바르다.


🟩 Spring Security를 이용한 "인가" 처리

http
                .authorizeHttpRequests((auth) -> auth
                        .requestMatchers("/", "/login").permitAll()
                        .requestMatchers("/getUserInfo").hasRole("ADMIN")
                        .anyRequest().authenticated()
                );
  • requestMatchers("/", "/login").permitAll()
    사용자의 request가 "/", "login" 경로일 경우 permitAll()(=모든 사용자가 접근이 가능하도록) 처리
  • requestMatchers("/getUserInfo").hasRole("ADMIN")
    사용자의 request가 "/getUserInfo" 경로일 경우 "ADMIN" 권한을 가진 사용자만 허용해준다.

🟩 Spring Security를 이용한 "인증" 처리

http
                .formLogin((auth) -> auth.loginPage("/login")       
                        .loginProcessingUrl("/loginProc")   
                        .defaultSuccessUrl("/login", true)
                        .permitAll()                         
                );
  • formLogin(): 폼 기반 로그인 사용
    • Spring Security에 폼 기반 로그인을 사용하겠다고 알려주는 설정
    • 기본적으로 Spring Security는 자체 로그인 폼을 제공하는데, 이 설정을 통해 커스텀 로그인 페이지를 지정할 수 있습니다.
  • loginPage("/login")
    • 사용자가 인증이 필요한 페이지(예: /admin)에 접근했을 때,
      로그인되지 않은 상태라면 Spring Security가 자동으로 /login 페이지로 리다이렉트합니다.
    • 즉, "/login"은 사용자가 로그인할 수 있도록 직접 만든 로그인 화면의 경로입니다.
  • loginProcessingUrl("/loginProc")
    • 사용자가 '/loginProc 요청을 보내면 Spring Security가 해당 요청을 가로채 로그인 처리를 수행
  • defaultSuccessUrl("/login", true)
    • 로그인 인증이 성공하고 난 후, Spring Security가 성공 후 "/login" 경로로 리다이랙트를 시도함
    • 파라미터로 사용되는 경로는 백엔드에서 실제로 존재하는 url 이어야 합니다. (존재하지 않는다면 404 에러가 발생할 수 있습니다..)
    • AJAX 기반 로그인 처리 방법으로 처리하게 되면 해당 코드는 작성이 필요 없다고 합니다.

이처럼 Spring Security를 이용해 "인증", "인가"에 대한 처리를 할 수 있습니다.


저는 [개발자 유미 유튜브] 를 참고하여 Spring Security 공부를 진행하고 있습니다.
영상에서는 SpringBoot 프로젝트만을 이용해서 알려주시기 때문에 제 코드와는 다른 부분이 있을 수 있습니다.

추가적인 이해나 설명이 더 필요하신 분들은 유튜브 들어가서 확인해 보시면 좋을 것 같습니다~!

0개의 댓글