这次为什么要把这样一个简单得东西,做的看起来很复杂。因为我觉得有必要把我自己对问题得分析过程分享给大家,让大家不在是遇到问题查不到资料时就不知道该怎么办了。我觉得学习不仅是要告诉大家怎么做,而且还要懂得怎么分析。
上个篇幅讲到了GlobalMethodSecurityConfiguration 这个配置类,而这个配置类是@EnableGlobalMethodSecurity(prePostEnabled = true)这个注解启用得。并且这里面也new 了一个 AffirmativeBased(一票通过)决策器。
现在总算知道为什么启动得时候这个决策器会进来两次了。因为GlobalMethodSecurityConfiguration 这个配置类new了一个
那么这个时候问题来了,使用@PreAuthorize 这个注解得时候到底是进了那个AffirmativeBased呢? 好的继续调试下看看
第一次进来对象@6044 这个是 GlobalMethodSecurityConfiguration
第二次进来对象@6344 这个是默认得
接下来看看 启动完成后拦截得时候进入了哪一个
发现两个都进来了。
并且发现第一次进来得result 就等于1 了 满足 一票通过制,可是为什么又进不去呢
第二次进来发现
来了个-1
第三次弃权
第四次弃权
再结合没加GlobalMethodSecurityConfiguration 这个注解前,是不存在权限问题,加了这个注解之后,就权限不足,那至少可以肯定得时候 这个校验肯定是走了GlobalMethodSecurityConfiguration 中new出来得 AffirmativeBased
距离目标似乎又近了一步。
接下来重点关注GlobalMethodSecurityConfiguration 做了什么事情,先不管它做了什么事情,先看看这个类中有没有多前缀做什么操作 搜索“Prefix”,发现如下代码
GrantedAuthorityDefaults grantedAuthorityDefaults = getSingleBeanOrNull(
GrantedAuthorityDefaults.class);
if (grantedAuthorityDefaults != null) {
this.defaultMethodExpressionHandler.setDefaultRolePrefix(
grantedAuthorityDefaults.getRolePrefix());
}
也就是说再这里如果grantedAuthorityDefaults 不为null 就去取这个值设置到defaultMethodExpressionHandler 这里面。
那么再看看grantedAuthorityDefaults 这个值哪里来,
private <T> T getSingleBeanOrNull(Class<T> type) {
try {
return context.getBean(type);
} catch (NoSuchBeanDefinitionException e) {}
return null;
}
由此可以看出来 是直接从 private BeanFactory context;中拿出来得,意味着我,给grantedAuthorityDefaults 注册到spring容器即可。好的继续试试
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("");
}
重启后发现,居然可以了。
那也就是说,
@EnableGlobalMethodSecurity(prePostEnabled = true)
@PreAuthorize("hasRole('user:list')")
这种形式得自定义前缀,可以通过设置GrantedAuthorityDefaults 这个来实现。