on
[Spring] @PreAuthorize, @PostAuthorize에서 Custom Security...
[Spring] @PreAuthorize, @PostAuthorize에서 Custom Security...
728x90
Spring Security에서 Annotation 형태로 Class, Method 레벨 단위로 권한별 접근제어 기능을 제공한다.
( https://joomn11.tistory.com/88 )
그중에서 @PreAuthorize, @PostAuthorize Annotation의 경우에는 SpringEL에서 제공하는 Expression 이외에도 사용자가 정의한 Custom Expression(Method)를 호출할 수 있는 기능을 제공한다.
해당 기능에 대해서 알아보도록 하자.
@PreAuthorize("isAuthenticated() and (( #user.name == principal.name ) or hasRole('ROLE_ADMIN'))") @RequestMapping( value = "", method = RequestMethod.PUT) public ResponseEntity updateProject( User user ){ updateProject.update( user ); return new ResponseEntity( new Project(), HttpStatus.OK ); }
우선 위의 예제와 같이 isAuthenticated, hasRole과 같은 Spring EL에서 기본제공하는 기능을 활용할 수도 있다.
다만, 사용자가 원하는 기능이 기본으로 제공하는 기능에 존재하지 않는 경우에는 문제가 될 수 있다.
이러한 경우를 커버하기 위해서 Spring Security에서는 Custom Expression을 사용할 수 있는 기능을 열어 두었다.
Component 생성
먼저, Custom Expression(Method)를 정의할 Component를 생성한다.
// @Service @Component("loginService") public class LoginService { public boolean pageReadRoleCheck() { return true; } }
@PreAuthorize, @PostAuthorize Annotation에서 사용
@GetMapping("/api/v1/projects") @PreAuthorize("@loginService.pageReadRoleCheck()") public List getProjectList() { return projectService.findAll(); }
위와 같이 간단하게 Custom Expression을 Spring Security Annotation에서 사용이 가능하다.
Param 정보 전달
추가적으로, Custom Expression에 필요한 정보를 Param으로 넘길 수도 있다.
#pj와 같이 사용하여 Annotation이 붙은 Method의 Param 정보도 전달 할 수 있다.
// @Service @Component("loginService") public class LoginService { public boolean pageReadRoleCheck(String id) { return true; } } ///// @GetMapping("/api/v1/projects") @PreAuthorize("@loginService.pageReadRoleCheck(#pj.id)") public List getProjectList(Project pj) { return projectService.findAll(); }
returnObject
@PostAuthorize의 경우에는 해당 Method의 수행 결과 값도 전달 할 수 있다.
returnObject라는 예약어를 사용하면 된다.
@PostAuthorize("@loginService.pageReadRoleCheck(returnObject.name)") @RequestMapping( value = "/{id}", method = RequestMethod.GET ) public Project getProject( @PathVariable("id") long id ){ return service.findOne(id); }
Annotation 활성화 설정 추가
마지막으로, 이러한 Annotation을 활성화 시키기 위해서는 설정을 추가해 주어야 한다.
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) public class ServerSecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //..... } }
728x90
from http://joomn11.tistory.com/89 by ccl(A) rewrite - 2021-11-27 19:28:07