SMALL

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<Project> updateProject( User user ){
    updateProject.update( user );
    return new ResponseEntity<Project>( 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<ProjectResponseDto> 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<ProjectResponseDto> 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 {
        //.....
   }
}

 

LIST

+ Recent posts