序言
SpringSecurity 进行的权限验证,有时候可能并不太满足我们的需求。有时候呢可能需要你自己去扩展达到一个对自己业务满意的验证,这时候怎么办呢?第一呢, 先不要百度,你要懂权限验证的一个流程,不懂的话可以去看我之前的博客,第二呢,就是放开手按照自己假象的思路去实践!
思路
我说一下我的需求,我想判断那个角色拥有某些url的权限,这时候该怎么进行扩展呢?
我的思路是对 自定义 AccessDecisionVoter
然后我们知道在 FilterSecurityInterceptor
里是从 SecurityMetadataSource
中拿到的权限配置项,知道了这些后,就可以做出扩展。
- 定义一个自己的
SecurityMetadataSource
使其从数据库中查询权限自己构建ConfigAttribute
- 定义一个具有自己需求的
AccessDecisionVoter
- 规定一个自己的
AccessDecisionManager
实践
SecurityMetadataSource
首先呢我们先定义一个自己的 SecurityMetadataSource
,然后每次调用的时候都去数据库里去查询。
public class DynamicFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
private FilterInvocationSecurityMetadataSource superMetadataSource;
public DynamicFilterInvocationSecurityMetadataSource(FilterInvocationSecurityMetadataSource expressionBasedFilterInvocationSecurityMetadataSource) {
this.superMetadataSource = expressionBasedFilterInvocationSecurityMetadataSource;
//TODO 在这里去查询你的数据库
}
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
/**
* 假设这就是从数据库中查询到的数据
* 意思就是 ROLE_JAVA 的角色 才能访问 /tt
*/
private final Map<String, String> urlRoleMap = new HashMap<String, String>() {
{
put("/tt", "ROLE_JAVA");
}};
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
FilterInvocation fi = (FilterInvocation) object;
String url = fi.getRequestUrl();
for (Map.Entry<String, String> entry : urlRoleMap.entrySet()) {
if (antPathMatcher.match(entry.getKey(), url)) {
return SecurityConfig.cre