结论:
在spring-security-5.1.6中
@PreAuthorize>@Secured>@RolesAllowed依次屏蔽;
上代码:
项目启动 {@link org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration#methodSecurityMetadataSource} 中解析 @EnableGlobalMethodSecurity注解
if (isPrePostEnabled) {
sources.add(new PrePostAnnotationSecurityMetadataSource(attributeFactory));
}
if (isSecuredEnabled) {
sources.add(new SecuredAnnotationSecurityMetadataSource());
}
if (isJsr250Enabled) {
GrantedAuthorityDefaults grantedAuthorityDefaults =
getSingleBeanOrNull(GrantedAuthorityDefaults.class);
Jsr250MethodSecurityMetadataSource jsr250MethodSecurityMetadataSource = this.context.getBean(Jsr250MethodSecurityMetadataSource.class);
if (grantedAuthorityDefaults != null) {
jsr250MethodSecurityMetadataSource.setDefaultRolePrefix(
grantedAuthorityDefaults.getRolePrefix());
}
sources.add(jsr250MethodSecurityMetadataSource);
}
添加顺序是(对下方向缓存中储存有影响) 1.PrePostAnnotationSecurityMetadataSource 2.SecuredAnnotationSecurityMetadataSource 3.jsr250MethodSecurityMetadataSource {@link org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource} 会把注解信息在 {@link org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource#getAttributes} 缓存到 attributeCache中
for (MethodSecurityMetadataSource s : methodSecurityMetadataSources) {
attributes = s.getAttributes(method, targetClass);
if (attributes != null && !attributes.isEmpty()) {
break;
}
}
因为PrePostAnnotationSecurityMetadataSource在SecuredAnnotationSecurityMetadataSource之前 所以循环找到@PreAuthorize就break掉,并将其缓存到attributeCache中 同理@Secured会使@RolesAllowed注解失效 {@link org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor#invoke} 调用 {@link org.springframework.security.access.intercept.AbstractSecurityInterceptor#beforeInvocation} Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource() .getAttributes(object); 在attributeCache获取注解信息,并进行之后的权限判断