@EnableMethodSecurity:Method Security
。Spring Security 6에서Method Security를 활성화하는어노테이션
▶ 주로@Configuration에 선언하여 개별 Method에 대해Method Security를 활성화하여접근제어를 적용.
。@Configuration외@Component등의Spring Bean에 선언하여 사용도 가능
。선언된@Configuration Class의 설정을 기반으로Spring Bean(@Service Class등 )의메서드 호출 시점에서Spring Security에 의해권한의검증을 수행하는어노테이션
。 기존@EnableGlobalMethodSecurity를 대체하여 더 유연하고 강력한 기능을 제공.
。해당Annotation을 선언하는 경우@PreAuthorize,@PostAuthorize,@Secured,@RolesAllowed등의Method 보안 Annotation을 선언가능.
- Method 보안 활성화 :
@PreAuthorize@RestController // Method 보안 Annotation를 선언할 수 있도록 @EnableMethodSecurity 선언. @EnableMethodSecurity(prePostEnabled = true) public class Security_Filter_Chain { private List<Todo> TODOS = new ArrayList<>(List.of(new Todo("wjdtn1", "UOS"), new Todo("wjdtn2","KHU"))); @GetMapping(path="/user/{username}/todos") // Application의 Authentication instance에 "ROLE_USER"의 역할이 존재 및 // 해당 instance의 username과 URL의 PathVariable로 전달되는 username이 일치해야 접근 가능. @PreAuthorize("hasRole('USER') and #username == authentication.name") public List<Todo> returnTodos(@PathVariable String username){ return TODOS; } }。
@PreAuthorize를 사용하기위해@EnableMethodSecurity(prePostEnabled = true)를 선언.
。@PreAuthorize에 의해 접근수준이 제한된Contoller Method에 접근하기 위해SecurityContextHolder에 저장되어 인증된 현재 로그인된 사용자정보(credentials,principal,authorities)를 포함하는 완전한Authentication instance의authorities가"ROLE_USER"의 권한을 포함해야하며Authentication instance의principal의username와URL의PathVariable로 전송된username과 일치하는 경우 Method에 접근허용.
▶"ROLE_USER"를 포함하면서username이wjdtn2로서 생성된JWT Token을HTTP Request의Authentication Header에 포함 및 해당username을URL Parameter로서 포함하여@PreAuthorize로 보호된Controller Method로 API 호출 시 정상적인 반환값을 도출.
。JWT Token과 다른username을URL Parameter로서 포함하여Controller Method로 API 호출 시 403오류 발생.
▶ 현재HTTP Request에 포함된JWT의username이 일치하는 사람의 경우에만 Controller Method에 접근하도록 제한이 가능
Method 보안 Annotation
。선행적으로@Configuration Class에@EnableMethodSecurity가 선언된 후Method에어노테이션을 선언하여 해당Method를 호출 시인증에 대한검증응 수행
▶ 현재는@PreAuthorize와@PostAuthorize를 주로 사용.
。@Secured의 경우@EnableMethodSecurity(securedEnabled = true),
@RolesAllowed의 경우@EnableMethodSecurity(jsr250Enabled = true)선언이 선행적으로 필요.
@PreAuthorize(SpEL):
。Method 실행 전의 권한을 검사하는 Annotation.
。SpEL( Spring Expression Language )를 사용하여 권한조건을 설정.
。@PreAuthorize를 사용하기전에Web Security @Configuration 클래스에@EnableMethodSecurity(prePostEnabled = true)를 선언해야함.@PreAuthorize("hasRole('USER') and #username == authentication.name") public List<Todo> returnTodos(@PathVariable String username){ return TODOS; }▶
SecurityContextHolder에 저장되어 인증된 현재 로그인된 사용자정보(credentials,principal,authorities)를 포함하는 완전한Authentication instance의authorities가"ROLE_USER"의 권한을 포함해야하며Authentication instance의principal의username와URL의PathVariable로 전송된username과 일치하는 경우 Method에 접근허용.
@PreAuthorize("#currentId == authentication.principal.id")
。void deleteAccount(UUID currentId);에서currentId가 현재SecurityContext에 등록된Authentication 구현체에 등록된authentication.principal.id랑 동일한 경우 허용
@PreAuthorize("hasRole('SUPERADMIN')")
。현재SecurityContext에 등록된Authentication 구현체의authorities = ROLE_SUPERADMIN인 경우 허용
@PreAuthorize("hasAnyRole('ADMIN', 'SUPERADMIN')")
。현재SecurityContext에 등록된Authentication 구현체의authorities = ROLE_ADMIN, ROLE_SUPERADMIN인 경우 허용
@PostAuthorize(SpEL):
。Method 실행 후 반환값을 기반으로 접근을 제어하도록 선언하는Annotation
▶ 주로 반환된 객체를 기반으로 권한을 확인 시 선언하여 활용.@PostAuthorize("returnObject.owner == authentication.name") public Order getOrder(Long orderId) { return orderService.findById(orderId); }▶ Method 실행 후 반환된
Orderinstance의Order.ownerfield가 현재HTTP Request의 사용자인증정보의Auticationinstance의authentication.name와 동일한 경우 접근을 허용.
@Secured("ROLE_권한명")
。특정Role을 기반으로 접근을 제어하는 Annotation
▶ 선행적으로 Class에@EnableMethodSecurity(securedEnabled = true)이 선언되야 한다.
。@PreAuthorize와 달리 기능이 제한적이며SpEL을 사용 불가능.
ex)@Secured("ROLE_ADMIN"):
▶ 해당 Method는"ROLE_ADMIN"의 권한을 가진 사용자만 접근허용하는Annotation.
@Secured({"ROLE_USER", "ROLE_ADMIN"})
"ROLE_USER"또는"ROLE_ADMIN"의 권한을 가진 사용자만 접근허용하는Annotation.
@RolesAllowed("ROLE_권한명")
。JSR-250의어노테이션으로서@Secured와 유사한 역할을 수행.
▶ 선행적으로@Configuration Class에@EnableMethodSecurity(jsr250Enabled = true)이 선언되야 한다.
。@PreAuthorize와 달리 기능이 제한적이며SpEL을 사용 불가능.
ex)@RolesAllowed({"ROLE_USER", "ROLE_ADMIN"})
"ROLE_USER"또는"ROLE_ADMIN"의 권한을 가진 사용자만 접근허용하는Annotation.