[SPRING] 컨트롤러에서 유효성 검사 (@Valid) 전에 보안 액세스 (@Secured 또는 @PreAuthorize)를 확인하는 방법은 무엇입니까?
SPRING컨트롤러에서 유효성 검사 (@Valid) 전에 보안 액세스 (@Secured 또는 @PreAuthorize)를 확인하는 방법은 무엇입니까?
여기 내 컨트롤러 코드 :
@PreAuthorize("hasRole('CREATE_USER')")
@RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public UserReturnRO createUser(@Valid @RequestBody UserRO userRO) throws BadParameterException{
return userService.createUser(userRO);
}
내 역할은 적절한 역할이없는 클라이언트가 사용자를 만들려고 할 때 컨트롤러가 보낸 데이터가 유효하지 않더라도 "승인되지 않음"으로 응답하는 것입니다. 그 대신 클라이언트가 적절한 역할이 없으면 잘못된 데이터로 사용자를 생성하려고 할 때 컨트롤러가 @Valid 메시지 (예 : "암호는 비워 둘 수 없음")로 응답하고 "승인되지 않은" .
PreAuthorized Interface에서이 문장을 찾을 수 있습니다 :
그러나 그것이 사실이 아닌 것처럼 보입니다.
해결법
-
==============================
1.@Valid는 실제 메서드 호출 전에 처리되고 @PreAuthorize보다 먼저 처리되므로이 작업은 직접 수행 할 수 없습니다.
@Valid는 실제 메서드 호출 전에 처리되고 @PreAuthorize보다 먼저 처리되므로이 작업은 직접 수행 할 수 없습니다.
하지만 대신 할 수있는 일은 BindingResult를 모델 (userRO) 바로 다음에 삽입하고 그로부터 유효성 검사 프로세스를 제어하는 것입니다. 그런 다음 BindingResult에 몇 가지 오류가 있는지 확인하고 잘못된 요청 응답을 반환하는지 확인합니다 (스프링과 유사).
예:
@ResponseBody @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("hasRole('CREATE_USER')") public ResponseEntity<?> createUser(@RequestBody @Valid UserRO userRO, BindingResult result) { if (result.hasErrors()) { return ResponseEntity.badRequest().body(result.getAllErrors()); } return ResponseEntity.ok(userService.createUser(userRO)); }
-
==============================
2.이미 언급했듯이, Spring Security의 @PreAuthorize는 메소드 advice이며, 메소드와 메소드의 인수가 이미 해결 될 때까지 참여하지 않는다는 것을 의미합니다.
이미 언급했듯이, Spring Security의 @PreAuthorize는 메소드 advice이며, 메소드와 메소드의 인수가 이미 해결 될 때까지 참여하지 않는다는 것을 의미합니다.
이미 주어진 대답과는 별도로, 인수를 해결하기 전에 권한을 이전 할 수있는 몇 가지 방법이 있습니다.
먼저, Spring Security는 요청이 메소드에 매핑되기 전에 URL을 검사합니다. 그리고 이것은 @Controller이기 때문에 대신 @PreAuthorize 대신 해당 레벨의 요청에 요청을 매핑 할 수 있다고 가정하는 것이 합리적입니다.
http .authorizeRequests() .mvcMatchers(POST, "/somepath").hasRole("CREATE_USER")
둘째, Spring MVC는 메서드 인수를 파싱하기 전에 권한을 확인하는 데 제한된 지원을 제공합니다. 예를 들어 다음과 같이 할 수 있습니다.
@EnableWebMvc public static class MvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { UserRoleAuthorizationInterceptor userRole = new UserRoleAuthorizationInterceptor(); userRole.setAuthorizedRoles("CREATE_USER"); registry.addInterceptor(userRole); } }
@PreAuthorize는 글로벌 설정이기 때문에 @PreAuthorize보다 훨씬 기본이지만 완벽을 기하기 위해 포함 시켰습니다.
세 번째 (경고, 일부 무능함), 독자적인 HandlerInterceptor를 생성 할 수 있습니다.
흐름은 다음과 같습니다.
따라서 HandlerInterceptor는 인수가 해결되기 전에 검사합니다. 그러나 MethodSecurityInterceptor만큼이나 복잡하지는 않습니다. 예를 들면 다음과 같습니다.
static class AuthorizationInterceptor extends HandlerInterceptorAdapter { SecurityMetadataSource securityMetadataSource; AccessDecisionManager accessDecisionManager; @Override public void preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { Authentication authenticated = (Authentication) request.getUserPrincipal(); MethodInvocation mi = convert(handler); Collection<ConfigAttribute> attributes = this.securityMetadataSource.getAttributes(mi); // throws AccessDeniedException this.accessDecisionManager.decide(authenticated, mi, attributes); return true; } }
그런 다음 함께 연결하십시오.
@EnableGlobalMethodSecurity(prePostEnabled = true) static class MethodConfig extends GlobalMethodSecurityConfiguration { @Bean HandlerInterceptor preAuthorize() throws Exception { return new AuthorizationInterceptor( accessDecisionManager(), methodSecurityMetadataSource()); } } @EnableWebMvc public static class MvcConfig implements WebMvcConfigurer { @Autowired AuthorizationInterceptor authorizationInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authorizationInterceptor); } }
MethodSecurityInterceptor가 승인 된 요청에 여전히 참여할 것이기 때문에 이는 상상할 수 없습니다.
from https://stackoverflow.com/questions/22780668/how-to-check-security-acess-secured-or-preauthorize-before-validation-vali by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 정적 함수에서 @Value 주석의 대안 (0) | 2019.07.17 |
---|---|
[SPRING] 스프링 부트 보안 - java.lang.IllegalArgumentException : null GrantedAuthority 콜렉션을 전달할 수 없음 (0) | 2019.07.17 |
[SPRING] 동기화를 사용할 때 Spring 파티션에서 예기치 않은 오류가 발생했습니다. (0) | 2019.07.17 |
[SPRING] SSL을 사용하여 Spring WebSocketClient를 사용하는 방법은 무엇입니까? (0) | 2019.07.17 |
[SPRING] Spring MVC 누락 행렬 변수 (0) | 2019.07.17 |