问题
@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;
}
}
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.
Any ideas?
EDIT:
@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.
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
}
回答1:
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.
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>
Or for RoleVoter
something like "ROLE_ADMIN"
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/admin/**"
access="ROLE_ADMIN" />
</security:http>
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.
EDIT
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 }
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
}
}
}
来源:https://stackoverflow.com/questions/24587531/spring-security-accessdecisionvoter