@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,始终都会调用表决方法。似乎只有support(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调用此方法,就像为"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>


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

10-06 01:18