개발/Spring

Spring Security에서 @EnableMethodSecurity 및 권한 관련 어노테이션 정리

피터JK 2025. 1. 29. 20:06
728x90

Spring Security에서 메소드 수준의 접근 제어를 구현할 때 @EnableMethodSecurity를 사용하며, 다양한 어노테이션(@PreAuthorize, @PostAuthorize, @Secured, @RolesAllowed)을 활용할 수 있습니다.


1. @EnableMethodSecurity란?

📍 @EnableMethodSecurity 개요

  • Spring Security 6.x 이상에서는 @EnableGlobalMethodSecurity가 Deprecated되고, 대신 **@EnableMethodSecurity**를 사용함.
  • 메소드 수준에서 보안 정책을 적용할 수 있도록 활성화하는 어노테이션.

📍 사용법 (Spring Security 6.x 기준)

@Configuration
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig {
}

 

옵션  설명
prePostEnabled = true @PreAuthorize, @PostAuthorize 어노테이션 활성화
securedEnabled = true @Secured 어노테이션 활성화
jsr250Enabled = true @RolesAllowed 어노테이션 활성화

2. @PreAuthorize 와 @PostAuthorize

📍 @PreAuthorize

  • 메소드 실행 전에 접근 권한을 검사
  • SpEL(Expression Language)을 사용하여 세부적인 조건 설정 가능
  • 메소드 실행을 막을 수 있음

🔹 사용 예시

@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin")
public String adminOnly() {
    return "Admin Page";
}

🔹 SpEL을 활용한 예시

@PreAuthorize("#username == authentication.name")
public User getUserProfile(String username) {
    return userService.findByUsername(username);
}

📍 @PostAuthorize

  • 메소드 실행 후에 접근 권한을 검사
  • 반환된 결과를 기반으로 접근을 제어할 때 사용

🔹 사용 예시

@PostAuthorize("returnObject.owner == authentication.name")
public Document getDocument(Long id) {
    return documentService.findById(id);
}
  • 반환된 객체(returnObject)의 owner 필드가 현재 로그인한 사용자와 일치해야 함.

⚠️ @PostAuthorize는 성능에 영향을 줄 수 있으므로, 권장되지 않음 → 대신 @PreAuthorize를 사용할 것.


3. @Secured

📍 @Secured 개요

  • Spring Security에서 제공하는 어노테이션 (JDK 기본 제공 X)
  • 단순한 권한 체크를 수행할 때 사용
  • SpEL을 지원하지 않음

🔹 사용 예시

@Secured("ROLE_ADMIN")
@GetMapping("/admin")
public String adminPage() {
    return "Admin Page";
}

🔹 여러 개의 권한을 허용할 경우

@Secured({"ROLE_ADMIN", "ROLE_MANAGER"})
public void manageUsers() {
    // 관리자와 매니저만 접근 가능
}

4. @RolesAllowed (JSR-250 표준)

📍 @RolesAllowed 개요

  • JSR-250 (Java 표준) 에서 제공하는 어노테이션
  • Spring Security에서도 지원되지만, 기본적으로 비활성화됨 (@EnableMethodSecurity(jsr250Enabled = true) 필요)
  • @Secured와 유사하지만, Java EE 표준을 따름

🔹 사용 예시

@RolesAllowed("ROLE_ADMIN")
public String adminPage() {
    return "Admin Page";
}

🔹 여러 개의 역할 허용

@RolesAllowed({"ROLE_ADMIN", "ROLE_MANAGER"})
public void manageUsers() {
    // ROLE_ADMIN 또는 ROLE_MANAGER가 있어야 접근 가능
}

5. 각 어노테이션 비교

 

어노테이션   지원 여부 특징 SpEL 지원
@PreAuthorize Spring Security 실행 권한 체크
@PostAuthorize Spring Security 실행 반환된 결과 기반 체크
@Secured Spring Security 단순 권한 체크
@RolesAllowed JSR-250 표준 단순 권한 체크

6. 실전 예제

@RestController
@RequestMapping("/api")
public class UserController {

    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/admin")
    public String adminOnly() {
        return "Admin Page";
    }

    @Secured("ROLE_USER")
    @GetMapping("/user")
    public String userOnly() {
        return "User Page";
    }

    @RolesAllowed({"ROLE_ADMIN", "ROLE_MANAGER"})
    @GetMapping("/manage")
    public String manage() {
        return "Manager or Admin Page";
    }

    @PreAuthorize("#username == authentication.name")
    @GetMapping("/profile/{username}")
    public String userProfile(@PathVariable String username) {
        return "User Profile for " + username;
    }

    @PostAuthorize("returnObject.owner == authentication.name")
    @GetMapping("/document/{id}")
    public Document getDocument(@PathVariable Long id) {
        return documentService.findById(id);
    }
}

7. 결론

 

선택 기준  추천 어노테이션
복잡한 권한 로직 적용 (SpEL 사용 가능) @PreAuthorize
반환된 객체를 기반으로 접근 제어 @PostAuthorize (비추천)
단순한 권한 체크 (Spring Security) @Secured
JSR-250 표준 권한 체크 @RolesAllowed

🚀 Spring Security에서 @EnableMethodSecurity를 활성화하고, 적절한 권한 어노테이션을 적용하면 메소드 수준에서 보안을 강화할 수 있습니다! 😊

728x90