我们在需要用户访问权限的网址上提供信息包,其布局如下:
用户需要ROLE_INFOPACK1才能访问/ InfoPacks / InfoPack1 /和ROLE_INFOPACK2以访问/ InfoPacks / InfoPack2 /等。
我们一直在添加包,所以要添加WebSecurityConfig() .antMatchers(" / InfoPacks / InfoPack1 / ** / *&#34)。hasAuthority(" ROLE_INFOPACK1) 在安全配置中的配置方法变得越来越大的同时,每次创建新包时都会意味着修改和重新部署。
自定义评估器会更好。例如,可以调用服务的东西 像:
hasPermission(Authentication auth, String targetURL) {
// search auth.GrantAuthorities for a match to targetURL
}
我看到这种与PreAuthorize一起使用的自定义权限表达式示例,但似乎没有办法使用URL authorizeRequests()。 (至少在版本4中)。
任何指示都会非常受欢迎。
答案 0 :(得分:0)
得知它,感谢http://www.baeldung.com/spring-security-custom-voter。 我的网络安全配置现在看起来像:
protected void configure(HttpSecurity http) throws Exception {
http
.headers()
.frameOptions().sameOrigin()
.and()
.csrf().disable()
.exceptionHandling()
.and()
.authorizeRequests()
....
.antMatchers("/Infopacks/**/*").authenticated().accessDecisionManager(accessDecisionManager())
..... etc
}
@SuppressWarnings("unchecked")
@Bean
public AccessDecisionManager accessDecisionManager() {
System.out.println("Arrive AccessDecisionManager");
List<AccessDecisionVoter<? extends Object>> decisionVoters
= Arrays.asList(
new WebExpressionVoter(),
new RoleVoter(),
new AuthenticatedVoter(),
new DynamicVoter());
return new UnanimousBased(decisionVoters);
}
DynamicVoter的投票方法看起来(丑陋的第一次测试 - 我知道它需要插孔工作),如:
@Override
public int vote(Authentication a, Object s, Collection clctn) {
String url = ((FilterInvocation) s).getRequestUrl();
int vote = ACCESS_ABSTAIN;
if (url.contains("/Infopack")) {
vote = ACCESS_DENIED;
for (GrantedAuthority ga:a.getAuthorities()) {
if (url.toUpperCase().contains(ga.getAuthority()) ) {
vote = ACCESS_GRANTED;
break;
}
}
}
return vote;
}
因此,用户授权系统只需将infopack名称添加为允许用户访问infopack目录的授权权限。您可以随意添加新的infopack目录,而无需更改代码。