Spring Security:AccessDecisionVoter [英] Spring Security: AccessDecisionVoter

查看:851
本文介绍了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 ConfigAttributes 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆