即使@PreAuthorize中未列出用户角色,也会调用自定义ConstraintValidator

时间:2017-05-02 14:10:55

标签: spring spring-mvc spring-boot spring-security

我有一个带有POST端点的Spring Boot应用程序,@ PreAuthorize角色定义和请求正文的自定义验证器:

@PreAuthorize("hasAnyRole('ROLE_OTHER')")
@RequestMapping(value = "post", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public String post(@RequestBody @Valid DummyDTO dummyDTO) {
...
}

1)当我使用错误的角色无效的请求正文调用端点时,会执行自定义验证代码,即ConstraintValidator.isValid(),并且得到400错误请求

2)当我使用错误角色有效请求正文调用端点时,会执行自定义验证代码ConstraintValidator.isValid(),并且我得到403禁

为什么在@PreAuthorize检查之前执行自定义验证代码?在这两种情况下我都希望得到403.

DEBUG 12776 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor    : Successfully Authenticated: org.springframework.security.authentication.TestingAuthenticationToken@bbd5887f: Principal: key; Credentials: [PROTECTED]; Authenticated: false; Details: null; Granted Authorities: ROLE_USER
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@41ba74ef, returned: 1
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
DEBUG 12776 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /post reached end of additional filter chain; proceeding with original chain
 INFO 12776 --- [nio-8080-exec-3] com.example.DummyValidator               : > isValid(): [valid]
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.a.i.a.MethodSecurityInterceptor    : Secure object: ReflectiveMethodInvocation: public java.lang.String com.example.MyController.post(com.example.DummyDTO); target is of class [com.example.MyController]; Attributes: [[authorize: 'hasAnyRole('ROLE_OTHER')', filter: 'null', filterTarget: 'null']]
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.authentication.TestingAuthenticationProvider
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.a.i.a.MethodSecurityInterceptor    : Successfully Authenticated: org.springframework.security.authentication.TestingAuthenticationToken@bbd5887f: Principal: key; Credentials: [PROTECTED]; Authenticated: false; Details: null; Granted Authorities: ROLE_USER
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@356a19a2, returned: -1
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.access.vote.RoleVoter@7290b3e0, returned: 0
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.access.vote.AuthenticatedVoter@16f3e525, returned: 0
DEBUG 12776 --- [nio-8080-exec-3] o.s.s.w.a.ExceptionTranslationFilter     : Access is denied (user is not anonymous); delegating to AccessDeniedHandler
org.springframework.security.access.AccessDeniedException: Access is denied
...

我的DTO:

public class DummyDTO {

@DummyConstraint
private String name;
...
}

约束:

@Documented
@Retention(RUNTIME)
@Target({TYPE, FIELD, PARAMETER, ANNOTATION_TYPE})
@Constraint(validatedBy = {DummyValidator.class})
public @interface DummyConstraint {
...
}

和验证者:

public class DummyValidator implements ConstraintValidator<DummyConstraint, String> {
    private static final Logger LOGGER = LoggerFactory.getLogger(DummyValidator.class);

    @Override
    public void initialize(DummyConstraint constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        LOGGER.info("> isValid(): [{}]", value);
        return "valid".equalsIgnoreCase(value);
    }
}

0 个答案:

没有答案