Spring Security에서 @PreAuthorize를 이용한 메소드 접근 제어

궁금하면 500원·2024년 5월 29일

미생의 스프링

목록 보기
12/47

@PreAuthorize는 Spring Security에서 메소드에 대한 접근 제어를 설정하는 데 사용되는 애너테이션입니다.

이 애너테이션은 메소드가 실행되기 전에 특정 권한이나 인증 상태를 검사할 수 있도록 해줍니다.

다음은 @PreAuthorize를 사용하는 방법에 대한 포스팅을 하였습니다.

1. 의존성 추가

Spring Security와 Spring AOP가 필요하므로,
Maven 또는 Gradle 프로젝트에 해당 의존성을 추가해야 합니다.

Maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Gradle

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-aop'

2. @EnableGlobalMethodSecurity 애너테이션 추가

Spring Security가 메소드 보안을 활성화하도록 설정합니다.
이 애너테이션은 Spring Security 설정 클래스에 추가합니다.

import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfig : WebSecurityConfigurerAdapter() {

    override fun configure(http: HttpSecurity) {
        http.authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll()
            .and()
            .logout().permitAll()
    }
}

3. @PreAuthorize 애너테이션 사용

이제 메소드에 @PreAuthorize 애너테이션을 사용하여 접근 제어를 설정할 수 있습니다.
예를 들어, 특정 역할이 있는 사용자만 접근할 수 있도록 설정할 수 있습니다.

import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.stereotype.Service

@Service
class MyService {

    @PreAuthorize("hasRole('ADMIN')")
    fun adminOnlyMethod() {
        // 관리자만 접근할 수 있는 로직
    }

    @PreAuthorize("hasAuthority('ROLE_USER') or hasRole('ADMIN')")
    fun userOrAdminMethod() {
        // 사용자 또는 관리자만 접근할 수 있는 로직
    }

    @PreAuthorize("isAuthenticated()")
    fun authenticatedUserMethod() {
        // 인증된 사용자만 접근할 수 있는 로직
    }

    @PreAuthorize("isAnonymous()")
    fun anonymousUserMethod() {
        // 인증되지 않은 사용자만 접근할 수 있는 로직
    }
}

표현식 설명

  • hasRole('ADMIN'): 사용자가 ADMIN 역할을 가지고 있는지 확인합니다.
  • hasAuthority('ROLE_USER'): 사용자가 ROLE_USER 권한을 가지고 있는지 확인합니다.
  • isAuthenticated(): 사용자가 인증된 상태인지 확인합니다.
  • isAnonymous(): 사용자가 인증되지 않은 상태인지 확인합니다

4. 사용 예제

아래는 @PreAuthorize 애너테이션이 적용된 REST API 컨트롤러의 예입니다.

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class MyController(private val myService: MyService) {

    @GetMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    fun getAdminData(): String {
        return "Admin data"
    }

    @GetMapping("/user")
    @PreAuthorize("hasAuthority('ROLE_USER') or hasRole('ADMIN')")
    fun getUserData(): String {
        return "User data"
    }

    @GetMapping("/public")
    @PreAuthorize("isAnonymous()")
    fun getPublicData(): String {
        return "Public data"
    }
}

5. 테스트하기

이제 Spring Security 설정과 @PreAuthorize 애너테이션을 적용한 메소드를 테스트해 보세요.

인증되지 않은 사용자가 /admin 엔드포인트에 접근하려고 하면 403 Forbidden 오류가 발생해야 하며, ADMIN 권한이 있는 사용자만 접근할 수 있어야 합니다.

6. 결론

@PreAuthorize 애너테이션을 사용하면 메소드 수준에서 세밀한 접근 제어를 구현할 수 있습니다.

이를 통해 보안이 강화된 애플리케이션을 구축할 수 있으며, 특정 사용자의 역할이나 인증 상태에 따라 메소드 접근을 제어할 수 있다는것을 배웠습니다.

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글