Spring Security에서 권한 검증을 위해 흔히 사용하는 애노테이션 @PreAuthorize.
보통 아래와 같이 사용한다.
@PreAuthorize("hasRole('ADMIN')")
그런데 이때 "ADMIN" 같은 문자열을 상수로 관리하고 싶어서 이렇게 바꿔보고 싶어진다.
const val ROLE_ADMIN = "ADMIN"
@PreAuthorize("hasRole(ROLE_ADMIN)") // 이렇게 쓰고 싶다!
하지만 이렇게 작성하면 애플리케이션 실행 중 예외가 발생한다.
SpelEvaluationException: EL1008E: Property or field 'ROLE_ADMIN' cannot be found
왜 안 될까?
@PreAuthorize 안에서 사용되는 표현식은 Spring Expression Language(SpEL)로 동작한다.
SpEL은 해당 표현식 안에서 Kotlin이나 Java의 상수, 변수, enum 등을 인식할 수 없다.
즉, 우리가 흔히 쓰는 다음과 같은 것들은 전부 사용할 수 없다.
- const val로 정의한 문자열 상수
- enum 값
- companion object의 변수
- object 혹은 class의 static 필드
SpEL은 단순한 문자열 표현식만 평가하기 때문에,
Java/Kotlin 코드 영역의 상수를 참조하려고 하면 그런 속성은 존재하지 않는다는 에러가 발생한다.
결론: 무조건 하드코딩해야 한다
// 이렇게만 가능
@PreAuthorize("hasAnyRole('ADMIN', 'CEO')")
아쉽지만 @PreAuthorize나 @PostAuthorize에서 사용할 권한 이름은 반드시 문자열로 직접 하드코딩해야 한다.
그럼 enum이나 const로 권한 이름 못 써?
- 네. 해당 애노테이션 내부에서는 불가능합니다
- 외부 로직(예: 서비스, 인증 처리 로직 등)에서는 자유롭게 사용 가능하지만,
- @PreAuthorize("...") 안에서는 오직 문자열 리터럴만 허용됩니다
📌 요약
- @PreAuthorize("hasRole(...)") 안에서 변수, 상수, enum 전부 사용할 수 없음
- SpEL은 Java/Kotlin 상수에 접근할 수 없음
- 반드시 "ADMIN", "CEO" 등 문자열로 하드코딩해야 함
'Spring Security' 카테고리의 다른 글
Spring Security @EnableWebSecurity(debug = true) 오류 해결 (1) | 2025.03.20 |
---|---|
[오류 해결] 스프링 시큐리티 로그인 실패 시 무한 재로그인 문제 해결 (1) | 2024.11.08 |
스프링 시큐리티 의존성만 추가했을 때 동작하는 것들 (0) | 2024.04.24 |