我正在使用Spring Security
(3.2.5.RELEASE)。我尝试实现以下方案:
@Secured
注释(使用@RequestMapping
注释)@Secured
注释的方法我希望所有人都可以访问(即使是匿名用户)。@Secured
注释的特定角色,则会使用@Secured
注释的方法。对于管理员用户,也应始终允许使用这些方法,但我不希望每次使用ROLE_ADMIN
注释时都放置@Secured
。这是我的HttpSession配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**")
.permitAll()
[...]
}
我可以使用@Secured
注释来注释我的控制器方法,并且它可以正常工作。唯一的问题是如何添加url-intercept matcher以允许所有具有角色ROLE_ADMIN
的用户在从@Secured
注释方法收集的访问规则之前。目前看起来@Secured
方法在过滤器链中排在第一位,而上面代码中添加到HttpSession
的规则是最后一个。如何添加首先(ROLE_ADMIN
permision)和last(对于所有未使用@Secured
permision注释的方法)的规则,@Secured
注释中的所有规则都将包含在这些规则中两个规则?为了更清楚,我想实现这样的事情(在链中):
1) allow all for users with ROLE_ADMIN
2) all rules from @Secured
3) allow methods not annotated with @Secured for all
答案 0 :(得分:1)
好的,我已经实现了这一点,但并不完全像问题那样。这就是我所做的:
AccessDecisionVoter
,对于admin。ACCESS_GRANTED
AccessDecisionManager
的创建:两个!!!一个用于拦截网址,一个用于拦截方法。这是我的AdminPermitVoter
public class AdminPermitVoter implements AccessDecisionVoter<Object> {
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
if(isAdmin(extractAuthorities(authentication))) {
return ACCESS_GRANTED;
}
return ACCESS_ABSTAIN;
}
Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
return authentication.getAuthorities();
}
private boolean isAdmin(Collection<? extends GrantedAuthority> authorities) {
for(GrantedAuthority authority : authorities) {
if(equalsIgnoreCase(ADMIN_ROLE_NAME, authority.getAuthority())) {
return true;
}
}
return false;
}
}
这是默认url interecption访问决策管理器的创建:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.accessDecisionManager(accessDecisionManager())
.anyRequest()
.permitAll()
[...other configs...]
}
@Bean(name = "accessDecisionManager")
public AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter> voters = new ArrayList<>();
voters.add(new AdminPermitVoter());
voters.add(new WebExpressionVoter());
voters.add(new RoleVoter());
voters.add(new AuthenticatedVoter());
return new AffirmativeBased(voters);
}
这是默认方法拦截访问决策管理器的创建:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@SuppressWarnings("rawtypes")
@Override
protected AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter> voters = new ArrayList<>();
voters.add(new AdminPermitVoter());
voters.add(new RoleVoter());
voters.add(new AuthenticatedVoter());
return new AffirmativeBased(voters);
}
}