Spring Security:AccessDecisionVoter [英] Spring Security: AccessDecisionVoter
问题描述
@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产生影响。
Can you explain me, how the first supports method is supposed to work? No matter how i change myBool, the vote-method is always invoked. It seems like only supports(Class clazz) has effect on the 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;
}
}
这基本上是我唯一的配置。
This is basically my only config.
这是我使用AccessDecisionManager的方式:
This is how I used the 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安全应用程序上下文配置,很难给出正确的答案,但对于您的问题,该方法的Javadoc说明如下:
Without your Spring Security Application Context Configuration, It is hard to give a correct answer but for your question, The Javadoc for the method states the following;
Indicates whether this AccessDecisionVoter is able to vote on the
passed ConfigAttribute.
此方法实际上是为 ConfigAttribute
调用的以下isAnonymous()
for WebExpressionVoter
This method is actual invoked for ConfigAttribute
like the following "isAnonymous()"
for 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
,都不会看到任何影响。希望这会有所帮助。
Both WebExpressionVoter
and RoleVoter
are implementations of AccessDecisionVoter
. Unless you are not trying to evaluate any ConfigAttribute
s as mentioned above. Your method will never be invoked thus you won't see any effect whether you return true
or false
. Hope this helps.
编辑
如果你看一下 AffirmativeBased AccessDecisionManager的决定
方法。
If you look at the AffirmativeBased AccessDecisionManager's decide
method.
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 }
它不使用支持( ConfigAttribute con)
方法。因此,您必须修改您的编码,以便检查如下工作。
It doesn't make use of supports(ConfigAttribute con)
method at all. Thus you have to modify your coding to check as below in order to it to work.
@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
}
}
}
这篇关于Spring Security:AccessDecisionVoter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!