- 메서드 보안을 통한 인가(Authorization)의 개념
- @EnableMethodSecurity 를 활용하여 메서드 수준에서 보안 활성화하기
- @PreAuthorize, @PostAuthorize 애너테이션 사용법
- 메서드 파라미터를 활용한 동적 인가
- SpEL 을 이용해서 유연한 접근 제어하기
메서드 보안 개요
URL 기반 인가는 요청 경로에 따라 접근을 제어하지만, 메서드 보안은 실제 서비스 계층이나 비즈니스 로직의 메서드 실행 여부를 제어한다
이러한 방식은 컨트롤러, 서비스 메서드 단위에서 더욱 정밀한 접근 제어를 가능하게 한다
@EnableMethodSecurity 설정하기
메서드 보안을 활성화하려면, Spring Security 설정 클래스에서 @EnableMethodSecurity 를 선언하면 된다
@Configuration
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
// URL 기반 설정과 병행할 수 있다
}
팁
- prePostEnabled = true 옵션을 활성화해야 @PreAuthorize 와 @PostAuthorize 애너테이션을 사용할 수 있다
- 메서드 보안은 URL 인가보다 우선 적용되며, 더욱 세밀한 제어를 제공한다
| 항목 | 설명 |
| @EnableMethodSecurity | 메서드 보안을 활성화하는 애너테이션 |
| prePostEnabled | @PreAuthorize, @PostAuthorize 애너테이션 사용여부 |
@PreAuthorize, @PostAuthorize 애너테이션
1. @PreAuthorize
메서드 실행 전에 접근 권한을 검사한다
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@Service
public class ReportService {
// 메서드 실행 전에 접근 권한을 확인한다
@PreAuthorize("hasRole('ADMIN')")
public String generateAdminReport() {
return "Admin Report";
}
@PreAuthorize("hasAnyRole('USER','ADMIN')")
public String generateUserReport() {
return "User Report";
}
}
- hasRole('ADMIN') : 관리자 권한이 있어야 실행 가능
- hasAnyRole('USER', 'ADMIN') : 일반 사용자 또는 관리자 권한이 있어야 실행 가능
2. @PostAuthorize
메서드를 일단 실행하고, 반환값을 기준으로 접근을 제어한다
import com.b1uffer.multisessiontest.entity.Document;
import com.b1uffer.multisessiontest.repository.DocumentRepository;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.stereotype.Service;
@Service
public class DocumentService {
private final DocumentRepository documentRepository;
DocumentService(DocumentRepository documentRepository) {
this.documentRepository = documentRepository;
}
// 문서를 조회한 후 반환한다
@PostAuthorize("returnObject.owner == authentication.name")
public Document getDocument(Long id) {
return documentRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("Document not found"));
}
}
반환된 객체의 owner 필드(returnObject.owner)가
현재 로그인한 사용자의 이름(authentication.name)과 일치해야 접근이 허용된다
팁
- @PreAuthorize 는 메서드 실행 전 제어, @PostAuthorize 는 실행 후 반환값 기반 제어이다
- @PostAuthorize 는 결과에 따라 접근을 제어할 때 유용하다
메서드 파라미터 기반 동적 인가
메서드 인자로 전달된 값(매개변수)에 따라 접근을 제어할 수 있다
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@Service
public class UserProfileService {
@PreAuthorize("#username == authentication.name")
public String getUserProfile(String username) {
return "userProfile : " + username;
}
}
- #username : 메서드 파라미터 참조
- authentication.name : 현재 로그인한 사용자의 이름
- 두 값이 같을때만 접근을 허용함
팁
- 파라미터 기반 인자는 "자기 자신만 조회 가능" 과 같은 제약을 구현할 때 유용하다
- 보통 사용자 ID나 이메일 기반 접근 제어에 많이 활용된다
| @PreAuthorize | 설명 |
| #파라미터명 | 메서드 인자 참조 |
| authentication.name | 현재 로그인한 사용자의 이름 |
SpEL(Spring Expression Language) 활용하기
Security 에서는 SpEL을 활용해서 매우 유연한 인가 조건을 정의할 수 있다
1. 예제
@PreAuthorize("hasRole('ADMIN') and #id == authentication.principal.id")
public String editUser(Long id) {
return "edit User : " + id;
}
- hasRole('ADMIN') : 관리자 권한이 있을때에만 이 메서드를 실행할 수 있음
- #id == authentication.principal.id : 파라미터로 받은 id가 로그인 사용자 id와 동일해야 허용함
2. SpEL 주요 키워드
| 키워드 | 설명 |
| authentication | 현재 인증 객체 |
| principal | 현재 사용자의 객체(UserDetails) |
| authorities | 권한 목록 |
| #파라미터명 | 메서드의 인자 참조 |
| returnObject | 반환 객체, @PostAuthorize 에서 사용함 |
팁
- SpEL을 통해 단순 권한 체크 이상의 비즈니스 로직 기반 접근 제어가 가능하다
- 지나치게 복잡한 표현식은 코드 가독성을 낮춘다. 커스텀 권한 체크 메서드로 분리하는게 좋다고 함
'Spring Boot > Security 쿠키,세션 기반 인증,인가' 카테고리의 다른 글
| 세션 기반 사용자 인가 구현 : 도메인 객체 보안(ACL) (0) | 2026.05.18 |
|---|---|
| 세션 기반 사용자 인가 구현 : URL 패턴 기반 인가 설정 (0) | 2026.05.15 |
| 세션 기반 사용자 인가 구현 : 인증과 인가의 관계 (0) | 2026.05.14 |
| Remember-Me : 보안 (0) | 2026.05.14 |
| Remember-Me : 설정 (0) | 2026.05.12 |