Spring Security

김현정·2025년 5월 8일
0
post-thumbnail

Spring Security

: Spring Security는 Spring 기반 애플리케이션의 인증(Authentication)과 권한 부여(Authorization)를 담당하는 강력한 보안 프레임워크이다. 웹 애플리케이션, RESTful API 및 기타 애플리케이션 유형에 대한 포괄적인 보안 솔루션을 제공한다.

Spring Security는 강력하고 사용자 정의가 자유로운 인증 및 접근 제어 프레임워크이다. Spring 기반 애플리케이션 보안의 사실상 표준이다.

Spring Security는 Java 애플리케이션에 인증과 권한 부여를 모두 제공하는 데 중점을 둔 프레임워크이다. 모든 Spring 프로젝트와 마찬가지로 Spring Security의 진정한 힘은 사용자 요구 사항을 충족하도록 쉽게 확장할 수 있다는 것이다.

Spring Security 특징

  • 인증 및 권한 부여에 대한 포괄적이고 확장 가능한 지원
  • 세션 고정, 클릭재킹, 크로스 사이트 요청 위조 등과 같은 공격으로부터 보호
  • 서블릿 API 통합
  • Spring Web MVC와의 선택적 통합
  • 인증(Authentication): 사용자 신원 확인
  • 권한 부여(Authorization): 인증된 사용자가 특정 리소스에 접근할 수 있는지 확인
  • 보안 취약점 방어: CSRF(Cross-Site Request Forgery), XSS(Cross-Site Scripting) 등으로부터 보호
  • 다양한 인증 방식 지원: 폼 로그인, HTTP Basic, OAuth2, JWT 등
  • 메소드 수준 보안: 특정 메소드 호출에 대한 권한 체크
  • 시큐리티 컨텍스트 전파: 쓰레드간 보안 컨텍스트 전파

Spring Security 설정

Gradle을 사용하는 경우 다음 목록에서처럼 dependencies클로저 에 세 줄(애플리케이션용, Thymeleaf 및 Spring Security 통합용, 테스트용)을 추가해야 합니다 .build.gradle

implementation 'org.springframework.boot:spring-boot-starter-security'
//  Temporary explicit version to fix Thymeleaf bug
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.2.RELEASE'
testImplementation 'org.springframework.security:spring-security-test'

Maven을 사용하면 다음 목록에서처럼 <'dependencies>요소 에 두 개의 추가 항목(하나는 애플리케이션용이고 다른 하나는 테스트용)을 추가해야 합니다 .pom.xml

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
	<groupId>org.thymeleaf.extras</groupId>
	<artifactId>thymeleaf-extras-springsecurity6</artifactId>
	<!-- Temporary explicit version to fix Thymeleaf bug -->
	<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-test</artifactId>
	<scope>test</scope>
</dependency>

Spring Security 주요 개념 설명

인증(Authentication)

인증은 사용자가 자신이 주장하는 사람인지 확인하는 과정이다. Spring Security에서는 AuthenticationManager가 인증을 담당하며, 실제 인증 로직은 AuthenticationProvider에서 수행한다.

권한 부여(Authorization)

권한 부여는 인증된 사용자가 특정 리소스에 접근할 수 있는지 결정하는 과정이다. Spring Security에서는 URL 패턴, 메소드 호출 등에 대한 접근 제어를 구성할 수 있다.

http
    .authorizeHttpRequests(authorize -> authorize
        .requestMatchers("/", "/home", "/css/**", "/js/**", "/h2-console/**").permitAll()
        .requestMatchers("/api/authenticate").permitAll()
        .requestMatchers("/admin/**").hasRole("ADMIN")
        .anyRequest().authenticated()
    )

보안 컨텍스트(Security Context)

SecurityContext는 현재 인증된 사용자의 정보를 저장한다. SecurityContextHolder를 통해 애플리케이션 어디서나 현재 인증된 사용자 정보에 접근할 수 있다.

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();

보안 관련 추가 기능

CSRF(Cross-Site Request Forgery) 보호

CSRF는 인증된 사용자가 자신도 모르게 공격자가 의도한 행동을 수행하도록 하는 공격이다. Spring Security는 기본적으로 CSRF 보호 기능을 제공한다.

// CSRF 보호 구성 (H2 콘솔과 API 요청은 제외)
.csrf(csrf -> csrf
    .ignoringRequestMatchers("/h2-console/**", "/api/**")
)

CSRF 보호는 Thymeleaf 템플릿에서 th:action 속성을 사용할 때 자동으로 CSRF 토큰이 포함됩니다:

<form th:action="@{/login}" method="post">
    <!-- CSRF 토큰이 자동으로 포함됨 -->
</form>

XSS(Cross-Site Scripting) 방어

XSS 공격은 웹 애플리케이션에 악성 스크립트를 삽입하는 공격이다. Thymeleaf는 기본적으로 출력 내용을 이스케이프 처리하여 XSS 공격을 방지한다.

<!-- 자동으로 이스케이프 처리됨 -->
<p th:text="${userInput}"></p>

<!-- 이스케이프를 비활성화하려면 (신뢰할 수 있는 데이터만 사용) -->
<p th:utext="${trustedHtml}"></p>

세션 관리

Spring Security는 세션 고정 공격, 동시 세션 제어 등 다양한 세션 관리 기능을 제공한다.

// 세션 관리 설정
.sessionManagement(session -> session
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // JWT 사용 시
    // .maximumSessions(1)   // 동시 세션 제한
    // .sessionFixation().migrateSession()  // 세션 고정 공격 방지
)

메소드 레벨 보안

메소드 호출에 대한 보안 설정을 어노테이션으로 구현할 수 있다.

@PreAuthorize("hasRole('ADMIN')")
public List<User> getAllUsers() {
    return userRepository.findAll();
}

@PostAuthorize("returnObject.username == authentication.name")
public User getUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}

OAuth2 인증 구현 방법

OAuth2 의존성 추가

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

OAuth2 설정

// SecurityConfig.java에 추가
.oauth2Login(oauth2 -> oauth2
    .loginPage("/login")
    .defaultSuccessUrl("/dashboard")
    .userInfoEndpoint(userInfo -> userInfo
        .userService(customOAuth2UserService)
    )
)
# application.properties에 추가
spring.security.oauth2.client.registration.google.client-id=your-client-id
spring.security.oauth2.client.registration.google.client-secret=your-client-secret
spring.security.oauth2.client.registration.google.scope=profile,email

spring.security.oauth2.client.registration.github.client-id=your-github-client-id
spring.security.oauth2.client.registration.github.client-secret=your-github-client-secret

0개의 댓글