Files
llm-wiki/raw/official-docs/spring-security-method-security.md

95 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: official-doc / Spring Security — Method Security (@PreAuthorize/@PostAuthorize + Unannotated-Method Backstop)
source_type: official-doc
url: https://docs.spring.io/spring-security/reference/servlet/authorization/method-security.html
archive_url:
related_branches: [feature-keycloak-spring-rs-role-mapping]
related_projects: [keycloak-patterns]
tags: [official-doc, keycloak-patterns, auth, spring-security]
created: 2026-07-18
---
# Spring Security — Method Security (@PreAuthorize / @PostAuthorize / SpEL / Unannotated-Method Backstop)
> Layer: `raw/official-docs/` — Spring Security Reference `servlet/authorization/method-security.html` 페이지의 verbatim 발췌.
> `feature-keycloak-spring-rs-role-mapping` 의 RBAC enforcement location **Alternative B**(method-level security — `@EnableMethodSecurity` + `@PreAuthorize("hasRole('admin-role')")`) 결정의 1차 근거. locality(보호 코드 옆에 규칙) + SpEL expressiveness(파라미터/리턴값) 뿐 아니라, **unannotated method 는 보호되지 않는다는 벤더 자신의 CRITICAL 경고 + catch-all `HttpSecurity` 규칙 지침**을 grounding 하기 위해 별도 보관.
## Parent / 활용 branch
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-keycloak-spring-rs-role-mapping]] | RBAC enforcement location Alternative B — `@EnableMethodSecurity` + `@PreAuthorize("hasRole('admin-role')")` 채택의 근거(활성화 방법 + SpEL 파라미터/리턴값 표현력). 동시에 **unannotated method 는 보호 안 됨 → catch-all `HttpSecurity` 규칙 필수**라는 벤더 backstop 경고를 명시적으로 grounding |
## 출처 / Source
- 원본 URL: https://docs.spring.io/spring-security/reference/servlet/authorization/method-security.html
- 아카이브 URL: (미수집)
- 저자 / 조직: Spring Security (Broadcom / Spring team)
- 발행일: rolling reference docs (버전 번호는 이 페이지 발췌 범위에 명시되지 않음)
- 마지막 확인일: 2026-07-18
## 왜 저장했는지 / Why archived
Method-level security(`@EnableMethodSecurity` + `@PreAuthorize`)를 채택하려는 결정은 (1) 활성화 방법과 SpEL 문법 근거뿐 아니라 (2) **"annotation 이 없는 메서드는 보호되지 않는다"는 벤더의 명시적 경고**를 함께 가지고 있어야 안전하게 채택 가능하다. 이 경고가 곧 method-only 전략의 backstop 요구사항(HttpSecurity catch-all rule)의 1차 근거이므로, 형제 문서 [[raw/official-docs/spring-security-authorization-defense-in-depth]](request+method 동시 사용을 다루는 개요 페이지)와 별도로 이 세부 메커니즘 페이지를 발췌 보관.
## 핵심 인용 / Key quotes (verbatim)
> [§Method Security] "You can activate it in your application by annotating any @Configuration class with @EnableMethodSecurity or adding <method-security> to any XML configuration file, like so:"
> [§Authorizing Method Invocation with @PreAuthorize] "This is meant to indicate that the method can only be invoked if the provided expression hasRole('ADMIN') passes."
> [§Using Method Parameters] "Additionally, Spring Security provides a mechanism for discovering method parameters so they can also be accessed in the SpEL expression as well."
> [§Method authorization is a combination of before- and after-method authorization] (code example, verbatim, contiguous lines):
> ```
> @Service
> public class MyCustomerService {
> @PreAuthorize("hasAuthority('permission:read')")
> @PostAuthorize("returnObject.owner == authentication.name")
> public Customer readCustomer(String id) { ... }
> }
> ```
> [§Comparing Request-Level Authorization to Method-Level Authorization] "It's important to remember that when you use annotation-based Method Security, then unannotated methods are not secured.
> To protect against this, declare a catch-all authorization rule in your HttpSecurity instance."
> [보충 — Method Security 개요] "Spring Boot Starter Security does not activate method-level authorization by default."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| SPRING-MS-C1 | Method security 는 `@Configuration` 클래스에 `@EnableMethodSecurity` 를 붙이거나(또는 XML `<method-security/>`) 활성화하며, 이후 `@PreAuthorize`/`@PostAuthorize`/`@PreFilter`/`@PostFilter` 로 method invocation(파라미터·리턴값 포함)을 authorize 할 수 있다 | [§Method Security] "You can activate it in your application by annotating any @Configuration class with @EnableMethodSecurity or adding <method-security> to any XML configuration file, like so:" | `official-vendor-doc` | Spring Security 6.x/7.x reference, Servlet 환경 | `@EnableMethodSecurity` 가 Spring Boot 자동설정에 포함된다는 것은 증명 안 함(오히려 반대 — 아래 SPRING-MS-C5 참조) |
| SPRING-MS-C2 | `@PreAuthorize` 는 SpEL 표현식(예: `hasRole('ADMIN')`)이 참일 때만 메서드가 실제로 호출되는 **사전(before-invocation)** 인가 체크다 | [§Authorizing Method Invocation with @PreAuthorize] "This is meant to indicate that the method can only be invoked if the provided expression hasRole('ADMIN') passes." | `official-vendor-doc` | `@EnableMethodSecurity` 가 켜진 Spring-managed bean 의 모든 메서드 | request-level(`authorizeHttpRequests`) 규칙과의 평가 순서·우선순위는 이 페이지 범위 밖 |
| SPRING-MS-C3 | SpEL 표현식은 method **parameter**(`@P`, Spring Data `@Param`, `-parameters` 컴파일 플래그, 또는 bytecode debug symbol 로 discovery)를 참조할 수 있다 | [§Using Method Parameters] "Additionally, Spring Security provides a mechanism for discovering method parameters so they can also be accessed in the SpEL expression as well." | `official-vendor-doc` | `hasPermission(#c, 'write')` 류 파라미터 기반 인가 결정 | 파라미터 discovery 순서(4가지 방법)의 우선순위 세부는 별도 발췌 필요 — 이 claim 은 "가능하다"만 보증 |
| SPRING-MS-C4 | `@PreAuthorize`(사전 체크)와 `@PostAuthorize`(사후 체크, `returnObject` SpEL 변수로 **리턴값** 접근 가능)를 같은 메서드에 함께 선언할 수 있으며, 예시로 `returnObject.owner == authentication.name` 이 제시된다 | 코드 예시(§ Method authorization is a combination of before- and after-method authorization): `@PreAuthorize("hasAuthority('permission:read')")` / `@PostAuthorize("returnObject.owner == authentication.name")` / `public Customer readCustomer(String id) { ... }` | `official-vendor-doc` | 리턴값 기반(예: ownership 검증) 인가 결정 — IDOR(Insecure Direct Object Reference) 방어 패턴 | `PermissionEvaluator`/`hasPermission` 기반 object-level ACL 전체 인프라까지 이 인용이 증명하지는 않음(별도 섹션) |
| SPRING-MS-C5 (CRITICAL — backstop) | **Annotation 기반 Method Security 를 쓸 때 annotation 이 없는 메서드는 보호되지 않는다.** 이를 막기 위해 `HttpSecurity` 인스턴스에 catch-all authorization 규칙을 선언하라고 명시적으로 지시한다. 별도로 "Spring Boot Starter Security 는 method-level authorization 을 기본으로 활성화하지 않는다"고도 명시한다 | [§Comparing Request-Level Authorization to Method-Level Authorization] "It's important to remember that when you use annotation-based Method Security, then unannotated methods are not secured. To protect against this, declare a catch-all authorization rule in your HttpSecurity instance." + "Spring Boot Starter Security does not activate method-level authorization by default." | `official-vendor-doc` | method-only(`@PreAuthorize` 단독) RBAC 전략을 채택하는 모든 코드베이스 — Alternative B 의 backstop 요구사항 직접 근거 | catch-all 규칙의 **정확한 shape**(예: `anyRequest().authenticated()` vs 더 세밀한 matcher)는 지정하지 않음 — "declare a catch-all rule" 만 지시, 구체 구현은 별도 결정 필요 |
## Usage Boundaries / 적용 경계
- 이 자료가 직접 증명하는 것:
- `SPRING-MS-C1`: `@EnableMethodSecurity` 활성화 방법 + 이후 사용 가능한 4개 annotation
- `SPRING-MS-C2`: `@PreAuthorize` 의 사전 체크 SpEL 시맨틱
- `SPRING-MS-C3`: SpEL 이 method parameter 를 참조할 수 있음(discovery 메커니즘 존재)
- `SPRING-MS-C4`: SpEL 이 method 리턴값(`returnObject`)을 참조할 수 있음(`@PostAuthorize` 조합)
- `SPRING-MS-C5`: unannotated method 는 method security 로 보호되지 않으며, 벤더가 HttpSecurity catch-all 규칙을 명시적으로 요구함 + Boot Starter Security 는 method security 를 기본 비활성 상태로 둠
- 이 자료가 증명하지 않는 것:
- method-level 과 request-level 규칙이 동시에 걸렸을 때의 정확한 평가 순서/충돌 처리(그건 [[raw/official-docs/spring-security-authorization-architecture]] 류의 별도 페이지 몫)
- catch-all `HttpSecurity` 규칙의 구체적 matcher 모양 — "선언하라"는 지시만 있고 정확한 DSL 코드는 이 문서가 예시로 보여주는 한 형태(`anyRequest().authenticated()`)일 뿐, 그것이 **유일한** 정답이라는 것은 증명 안 함
- `feature-keycloak-spring-rs-role-mapping` 의 실제 `admin-role` naming, `JwtAuthenticationConverter` 매핑 등 프로젝트 구체 구현의 정확성 — 그건 [[raw/official-docs/spring-security-resource-server-jwt]] 의 몫
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
- P3A 실제 구현에서 `SecurityFilterChain` 에 catch-all `anyRequest().authenticated()` 를 실제로 선언했는지, 그리고 `@PreAuthorize` 가 없는 다른 엔드포인트가 실제로 열려 있지 않은지 로컬 curl 검증 필요
- `@EnableMethodSecurity` 를 명시적으로 켰는지(Boot Starter Security 기본 비활성이므로) 로컬 설정 확인 필요
## 메모 / Notes
- 이 페이지는 형제 문서 [[raw/official-docs/spring-security-authorization-defense-in-depth]] (Alternative C — request+method 동시 사용 개요)가 예고했던 "하위 세부 페이지" 중 하나(`servlet/authorization/method-security.html`)다. 개요 페이지는 "defense in depth" 프레이밍만 제공하고, 이 페이지가 그 defense-in-depth 가 **왜 필요한지**(unannotated method 미보호)의 구체 메커니즘 근거를 제공한다.
- SPRING-MS-C5 의 인용 원문은 컬리 어포스트로피(`It's``Its`, U+2019)를 사용한다 — 발췌 시 원문 그대로 보존.
- 추가로 봐야 할 동일 출처 페이지: `servlet/authorization/authorize-http-requests.html` (request-level DSL 세부), `servlet/architecture.html` (AuthorizationManager 아키텍처).
## Related / 관련
- [[raw/official-docs/spring-security-authorization-defense-in-depth]] — request-based + method-based 조합을 "defense in depth" 로 명명한 상위 개요 페이지 (Alternative C 근거)
- [[raw/official-docs/spring-security-authorization-architecture]] — `AuthorizationManager` / method security 세부 아키텍처 근거
- [[raw/official-docs/spring-security-resource-server-jwt]] — JWT 인증 + authority mapping (같은 branch 의 authN 근거)