개발/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