@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,都会调用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<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
}
答案 0 :(得分:3)
如果没有Spring安全应用程序上下文配置,很难给出正确答案,但对于您的问题,该方法的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
}
}
}