@Service
public class MyVoter implements AccessDecisionVoter<Entity> {
@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<ConfigAttribute> config) {
return ACCESS_GRANTED;
}
}
您能解释一下,第一种支持方法应该如何工作?无论我如何更改myBool,始终都会调用表决方法。似乎只有support(Class clazz)对调用有影响。
有任何想法吗?
编辑:
@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<String, AccessDecisionVoter> beans = context
.getBeansOfType(AccessDecisionVoter.class);
List<AccessDecisionVoter> decisionVoters = new ArrayList<>(
beans.values());
AffirmativeBased affirmativeBased = new AffirmativeBased(decisionVoters);
return affirmativeBased;
}
}
这基本上是我唯一的配置。
这就是我使用AccessDecisionManager的方式:
/* AUTHORIZATION */
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
Collection<ConfigAttribute> config = new HashSet<ConfigAttribute>();
config.add(new SecurityConfig("Something"));
try {
adm.decide(authentication, project, config);
} catch (Exception e) {
// .. Exception Handling
}
最佳答案
没有Spring Security应用程序上下文配置,很难给出正确的答案,但是对于您的问题,该方法的Javadoc指出以下内容;
Indicates whether this AccessDecisionVoter is able to vote on the
passed ConfigAttribute.
实际为
ConfigAttribute
调用此方法,就像为"isAnonymous()"
的以下WebExpressionVoter
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/login*"
access="isAnonymous()" />
</security:http>
或
RoleVoter
之类的"ROLE_ADMIN"
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/admin/**"
access="ROLE_ADMIN" />
</security:http>
WebExpressionVoter
和RoleVoter
都是AccessDecisionVoter
的实现。除非您不尝试如上所述评估任何ConfigAttribute
。您的方法将永远不会被调用,因此无论您返回true
还是false
,您都不会看到任何效果。希望这可以帮助。编辑
如果您查看AffirmativeBased AccessDecisionManager的
decide
方法。public void More ...decide(Authentication authentication, Object object, Collection<ConfigAttribute> 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<Entity> {
@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<ConfigAttribute> config) {
if(supports(config)) { // Add this check
return ACCESS_GRANTED;
} else {
return ACCESS_DENIED; // Abstain Based on your requirement
}
}
}