java - Spring 安全: AccessDecisionVoter

标签 java spring security vote

@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,投票方法始终会被调用。看来只有supports(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 调用的,就像以下 WebExpressionVoter"isAnonymous()"

<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>

WebExpressionVoterRoleVoter 都是 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
        }
    }
}

关于java - Spring 安全: AccessDecisionVoter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24587531/

相关文章:

security - 为什么这些 Botan 公钥如此相似?

php - 加盐密码安全

java - 如何动态地将 swt 小部件添加到复合 Material 中?

spring - Jetty 和 tomcat 不加载 AbstractAnnotationConfigDispatcherServletInitializer 的实现

javascript - 如何确保只有我自己的网站(客户端代码)可以与 Firebase 后端对话?

java - Spring 3.0 中 Post 函数不绑定(bind)

java - Spring - 使用 TransactionManager

java - Spring for Android 内存问题

java - "For each"两个对象的循环

java - Apache Camel : SFTP endpoint - Pipe closed issue