728x90
@Secured
- @Secured 어노테이션을 메소드에 적용하면 지정된 권한(역할)을 가진 사용자만 해당 메소드를 호출할 수 있으며 더 풍부한 형식을 지원하는 @PreAuthorize 사용을 권장
- @Secured 어노테이션을 사용하려면 스프링 시큐리티 설정에서 @EnableMethodSecurity(securedEnabled = true) 설정을 활성화해야 함
@Secured("ROLE_USER")
public void performUserOperation() {
// ROLE_USER 권한을 가진 사용자만 이 메소드를 실행 가능
}
JSR-250
- JSR-250 기능을 적용하면 @RolesAllowed, @PermitAll 및 @DenyAll 어노테이션 보안 기능이 활성화
- JSR-250 어노테이션을 사용하려면 스프링 시큐리티 설정에서 @EnableMethodSecurity(jsr250Enabled = true) 설정을 활성화해야 함
@RolesAllowed("USER")
public void editDocument() {
// 'ROLE_USER' 권한을 가진 사용자만 문서를 편집 가능
}
@PermitAll
public void viewDocument() {
// 모든 사용자가 문서 확인 가능
}
@DenyAll
public void hiddenMethod() {
// 어떠한 사용자도 접근 불가
}
메타 주석 사용
- 메서드 보안은 애플리케이션의 특정 사용을 위해 편리성과 가독성을 높일 수 있는 메타 주석을 지원
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('ADMIN')")
public @interface IsAdmin {}
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@PostAuthorize("returnObject.owner == authentication.name")
public @interface RequireOwnership {}
- @PreAuthorize("hasRole('ADMIN')")를 다음과 같이 @IsAdmin으로 간소화 가능
@IsAdmin
public BankAccount readAccount() {
// ADMIN 권한을 가진 사용자에게 메소드 호출이 승인 될 수 있음
}
@RequireOwnership
public Account readAccount(Long name) {
// 'Account'가 로그인한 사용자에게 속할 경우에만 반환
}
특정 주석 활성화
- Method Security의 사전 구성을 비활성화한 다음 @PostAuthorize를 활성화
@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor postAuthorize() {
return AuthorizationManagerAfterMethodInterceptor.postAuthorize();
}
}
커스텀 빈을 사용하여 표현식 구현
@GetMapping("/delete")
@PreAuthorize("@authorizer.isUser(#root)") //빈 이름을 참조하고 접근 제어 로직을 수행
public void delete(){
System.out.println("delete");
}
@Component("authorizer")
class MyAuthorizer{
public boolean isUser(MethodSecurityExpressionOperations root){
boolean decision = root.hasAuthority("ROLE_USER"); // 인증된 사용자가 ROLE_USER 권한을 가지고 있는지 검사
return dicision;
}
}
- 이전에 표현식 및 커스텀 구현에서 빈은 선언하고 그 안의 메서드를 사용했던 것과 같은 방식
→ @authorizer 빈에 있는 isUser() 메서드를 호출하고 root 라는 객체를 전달 - 사용자 정의 빈을 생성하고 새로운 표현식으로 사용할 메서드를 정의하고 권한 검사 로직을 구현
클래스 레벨 권한 부여
- 모든 메소드는 클래스 수준의 권한 처리 동작을 상속
@Controller
@PreAuthorize("hasAuthority('ROLE_USER')")
public class MyController {
@GetMapping("/endpoint")
public String endpoint() { ... }
}
@Controller
@PreAuthorize("hasAuthority('ROLE_USER')")
public class MyController {
@GetMapping("/endpoint")
@PreAuthorize("hasAuthority('ROLE_ADMIN')") // 이 설정이 우선적으로 동작한다
public String endpoint() { ... }
}
- 메서드에 어노테이션을 선언한 메소드는 클래스 수준의 어노테이션을 덮어쓰게 됨
→ 클래스에 설정한 것보다 메서드에 설정한 것이 더 높은 우선 순위를 가짐 - 인터페이스에도 동일한 규칙이 적용되지만 클래스가 두 개의 다른 인터페이스로부터 동일한 메서드의 어노테이션을 상속받는 경우에는 시작할 때 실패
→ 따라서 구체적인 메소드에 어노테이션을 추가함으로써 모호성을 해결 가능
728x90
'Language > Spring Security' 카테고리의 다른 글
계층적 권한 - RoleHireachy (0) | 2024.07.31 |
---|---|
정적 자원 관리 (0) | 2024.07.31 |
메서드 기반 권한 부여 - @PreFilter, @PostFilter (0) | 2024.07.31 |
메서드 기반 권한 부여 - @PreAuthorize, @PostAuthorize (0) | 2024.07.31 |
요청 기반 권한 부여 - HttpSecurity.securityMatcher() (0) | 2024.07.31 |