Spring Security:AccessDecisionVoter

@Service public class MyVoter implements AccessDecisionVoter { @Override public boolean supports(ConfigAttribute attribute) { boolean myBool = false; return myBool; } @Override public boolean supports(Class clazz) { return clazz == Project.class; } @Override public int vote(Authentication authentication, Entity someEntity, Collection config) { return ACCESS_GRANTED; } } 

你能解释一下,第一个支持方法应该如何工作? 无论我如何更改myBool,都会调用vote-method。 似乎只支持(Class clazz)对invokation有影响。

有任何想法吗?

编辑:

 @Configuration @EnableWebMvcSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired ApplicationContext context; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http .authorizeRequests() .antMatchers("/").permitAll() .anyRequest().authenticated(); http .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER"); } @Bean public AffirmativeBased accessDecisionManager() { Map beans = context .getBeansOfType(AccessDecisionVoter.class); List decisionVoters = new ArrayList( beans.values()); AffirmativeBased affirmativeBased = new AffirmativeBased(decisionVoters); return affirmativeBased; } } 

这基本上是我唯一的配置。

这就是我使用AccessDecisionManager的方式:

  /* AUTHORIZATION */ Authentication authentication = SecurityContextHolder.getContext() .getAuthentication(); Collection config = new HashSet(); config.add(new SecurityConfig("Something")); try { adm.decide(authentication, project, config); } catch (Exception e) { // .. Exception Handling } 

如果没有Spring安全应用程序上下文配置,很难给出正确答案,但对于您的问题,该方法的Javadoc说明如下:

 Indicates whether this AccessDecisionVoter is able to vote on the passed ConfigAttribute. 

实际为ConfigAttribute调用此方法,如下面的"isAnonymous()" for WebExpressionVoter

    

或者对于RoleVoter ,例如"ROLE_ADMIN"

    

WebExpressionVoterRoleVoter都是AccessDecisionVoter实现。 除非您没有尝试评估上面提到的任何ConfigAttribute 。 永远不会调用您的方法,因此无论您返回true还是false都不会看到任何影响。 希望这可以帮助。

编辑

如果你看一下AffirmativeBased AccessDecisionManager的decide方法。

 public void More ...decide(Authentication authentication, Object object, Collection configAttributes) 46 throws AccessDeniedException { 47 int deny = 0; 48 49 for (AccessDecisionVoter voter : getDecisionVoters()) { 50 int result = voter.vote(authentication, object, configAttributes); 51 52 if (logger.isDebugEnabled()) { 53 logger.debug("Voter: " + voter + ", returned: " + result); 54 } 55 56 switch (result) { 57 case AccessDecisionVoter.ACCESS_GRANTED: 58 return; 59 60 case AccessDecisionVoter.ACCESS_DENIED: 61 deny++; 62 63 break; 64 65 default: 66 break; 67 } 68 } 69 70 if (deny > 0) { 71 throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied", 72 "Access is denied")); 73 } 74 75 // To get this far, every AccessDecisionVoter abstained 76 checkAllowIfAllAbstainDecisions(); 77 } 

它根本不使用supports(ConfigAttribute con)方法。 因此,您必须修改您的编码以检查如下,以使其工作。

 @Service public class MyVoter implements AccessDecisionVoter { @Override public boolean supports(ConfigAttribute attribute) { boolean myBool = false; return myBool; } @Override public boolean supports(Class clazz) { return clazz == Project.class; } @Override public int vote(Authentication authentication, Entity someEntity, Collection config) { if(supports(config)) { // Add this check return ACCESS_GRANTED; } else { return ACCESS_DENIED; // Abstain Based on your requirement } } }