Spring Security

박수오·2025년 2월 19일
post-thumbnail

Spring Security(이하 Security 또는, 시큐리티)는 애플리케이션의 인증(Authentication)과 인가(Authorization)를 담당하는 보안 프레임 워크이다.

로그인, 권한 관리, 세션 관리 등의 보안 관련 기능을 제공한다.
OAuth2, JWT, Basic Auth, Form Login 등 다양한 인증 방식을 지원한다.

기본적으로 세션 기반 인증 을 제공한다.

Spring Security의 특징

인증(Authentication)

사용자가 올바른 자격증명(id/pw, OAuth 토큰 등)을 제공했는지 확인한다.
일반적으로 로그인 처리와 관련되며, UserDetailService와 AutheticationManager를 통해 인증을 수행한다.

인증 예제(사용자 정보 관리)

@Bean
public UserDetailsService userDetailsService() {
    UserDetails user = User.withDefaultPasswordEncoder()
        .username("user")
        .password("password")
        .roles("USER")
        .build();
    return new InMemoryUserDetailsManager(user);
}

인가(Authorization)

사용자가 특정 작업을 수행할 권한이 있는지 확인한다.
특정 페이지 또는 API에 대한 접근 권한을 검사한다.
역할(Role) 기반의 접근제어 (RBAC) 또는 권한(Permission)기반 접근 제어 가 가능하다.

인가 설정 예제(권한에 따라 접근 제한)

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/admin/**").hasRole("ADMIN") // 관리자만 접근 가능
                .requestMatchers("/user/**").hasRole("USER")   // 일반 사용자 접근 가능
                .anyRequest().authenticated()
            )
            .formLogin(withDefaults());  // 기본 로그인 폼 제공
        return http.build();
    }
}

비밀번호 암호화

시큐리티는 보안을 위해 비밀번호를 평문으로 저장하지 않고, 암호화 하여 저장 하도록 권장한다.
BCryptPasswordEncoder를 사용하면 비밀번호를 안전하게 해싱할 수 있다.

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

###
@autowired
public PasswordEncoder passwordEncoder;
~~~
passwordEncoder.encode(rawPassword);

세션 및 CSRF(Cross-Site Request Forgery) 보호

CSRF:공격자가 사용자의 인증 정보를 악용하여 원치 않는 요청을 수행하게 하는 공격
기본적으로 POST, PUT, DELETE 요청은 CSRF 토큰을 필요로 한다.

OAuth2 및 JWT 지원(토큰 기반 인증)

OAuth2: 구글, 네이버, 카카오 등 소셜 로그인에 사용된다.
JWT: 토큰 기반 인증을 활용하여 세션 없이 인증이 가능하게 한다. (REST API와 잘 맞는다.)

OAuth2 로그인 설정 예시

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth
            .anyRequest().authenticated()
        )
        .oauth2Login(withDefaults()); // OAuth2 소셜 로그인 활성화
    return http.build();
}

JWT 인증 방식 적용 예제

http
    .authorizeHttpRequests(auth -> auth
        .anyRequest().authenticated()
    )
    .oauth2ResourceServer(oauth2 -> oauth2.jwt()); // JWT 인증 적용

Spring Security Architecture

  1. SecurityFilterChain이 사용자 로그인 요청을 가로챔.
  2. UsernamePasswordAuthenticationFilter가 로그인 요청을 감지
  • SecurityFilterChain에 의해 요청이 UsernamePasswordAuthenticationFilter로 전달되고, 인증용 객체(Authentication Token)를 생성함.

   3,4 . AuthenticationManager가 구현체인 AuthenticationProvider를 통해 인증 시도

   5,6. UserDetailsService에서 사용자 정보를 조회

  1. authenticationProvider(들)은 UserDetails를 넘겨받고 사용자 정보를 비교한다.

  2. 인증이 완료되면 권한 등의 사용자 정보를 담은 Authentication 객체를 반환한다.

  3. 다시 최초의 AuthenticationFilter에 Authentication 객체가 반환된다.

  4. Authenticaton 객체를 SecurityContext에 저장한다.

주요 컴포넌트들

SecurityFilterChain - 요청을 가로채는 필터들의 체인

UsernamePasswordAuthenticationFilter - 로그인 요청 처리 (아이디/비밀번호 검증)

SecurityContextHolder - 현재 사용자의 인증 정보를 저장하는 컨텍스트

AuthenticationManager - 인증 요청을 처리하는 관리자

UserDetailsService - DB에서 사용자 정보를 조회하는 서비스

AuthenticationProvider - 실제 인증 로직을 처리

AccessDecisionManager - 인가(Authorization) 결정 로직

SecurityContextPersistenceFilter - SecurityContext를 유지
profile
모호하게 알고있거나 개념없이 사용만 했던 것들을 정리한 내용입니다.

0개의 댓글