[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