Announcement Announcement Module
No announcement yet.
"OR" AccessDecision Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • "OR" AccessDecision


    I would like to secure something like so: A and (B or C).

    I see 2 approaches -

    a) write a CompositeUnanimousBased AccessDecisionManager that accepts multiple lists of voters, and requires all lists to return at least 1 access granted.

    b) use the existing UnanimousBased, and create a CompositeAffirmativeVoter that delegates its vote to a list of voters.

    Reading through the documentation, it seems like the general recommendation is make voters as simple as possible, and the access decision manager should handle any/all combinatorial logic. But, a Composite voter seems much easier to implement, and the config would be simpler (at least to look at).

    Has anyone tried either? What is the recommended approach?

  • #2
    Are A, B, and C different classes of authorization checks? It's possible, for example, to do some simple boolean role checks using the standard voters (and especially with the SpEL support in Spring Sec 3).

    I like the first approach you described better, myself. Another option would be if you had something like an "access decision manager voter", where the voter would simply delegate its decision to another decision manager. In this way, you wouldn't be required to write your own decision manager.


    • #3
      I was assuming that A, B, and C were all the same classes. I do like your AccessDecisionVoter idea, I think I will look into that. Thanks!


      • #4
        So I started writing a DelegatingAccessDecisionVoter, which accept an AccessDecisionManager in the constructor. Here is what I have:

        public class DelegatingAccessDecisionVoter implements AccessDecisionVoter {
        	private AccessDecisionManager accessDecisionManager;
        	public DelegatingAccessDecisionVoter(
        			AccessDecisionManager accessDecisionManager) {
        				"An AccessDecisionManager is mandatory");
        		this.accessDecisionManager = accessDecisionManager;
        	public boolean supports(ConfigAttribute attribute) {
        		return accessDecisionManager.supports(attribute);
        	public boolean supports(Class clazz) {
        		return accessDecisionManager.supports(clazz);
        	public int vote(Authentication authentication, Object object,
        			ConfigAttributeDefinition config) {
        		Iterator iter = config.getConfigAttributes().iterator();
        		while (iter.hasNext()) {
        			ConfigAttribute attr = (ConfigAttribute);
        			if (this.supports(attr)) {
        				try {
        							.decide(authentication, object, config);
        				} catch (AccessDeniedException e) {
        					return AccessDecisionVoter.ACCESS_DENIED;
        				} catch (InsufficientAuthenticationException e) {
        					return AccessDecisionVoter.ACCESS_DENIED;
        				return AccessDecisionVoter.ACCESS_GRANTED;
        		return AccessDecisionVoter.ACCESS_ABSTAIN;
        	public AccessDecisionManager getAccessDecisionManager() {
        		return accessDecisionManager;
        This does allow me to use existing decision managers, but I seem unable to support this scenario: (Role_A AND (Role_B OR Role_C).

        The config attribute definition would be ["Role_A", "Role_B", "Role_C"]

        Here is the config I tried (unsuccessfully):

        HTML Code:
            -> supports "Role_A"
              -> supports "Role_B"
              -> supports "Role_C"
        With this config (and my above implementation of the Delegating voter), a user that has only "Role_A" is still granted access.

        I understand expression support in the upcoming release may make this AND/OR logic possible, but does anyone see a way to make it work in 2.0?


        • #5
          The way that you've built it is exactly what I was suggesting, and it should work. Have you tried stepping through with a debugger? If you have this configured as you described, it should be easy to figure out what the issue is.