Announcement Announcement Module
Collapse
No announcement yet.
How to add voters to the default accessDecisionManager? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to add voters to the default accessDecisionManager?

    Hello everyone

    Is there a simple way to add a voter to the "default" accessDecisionManager that is created when using the namespace configuration? I currently define an own accessDecisionManager bean and pass its reference to other tags like the global-method-security element. To do this, I had to first find out what voters the namespace config is creating by default. With lots of googling I ended with this config:


    Code:
    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    	<property name="decisionVoters">
    		<list>
    			<bean class="org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter">
    				<constructor-arg>
    					<bean class="org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice" />
    				</constructor-arg>
    			</bean>
    			<bean class="our.special.Voter" />
    			<bean class="org.springframework.security.access.vote.RoleVoter" />
    			<bean class="org.springframework.security.access.vote.RoleVoter">
    				<property name="rolePrefix" value="OP_" />
    			</bean>
    			<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
    		</list>
    	</property>
    </bean>
    
    <sec:global-method-security access-decision-manager-ref="accessDecisionManager"
    	pre-post-annotations="enabled" />
    Is this reasonable?

    This I think is a general "problem" with spring namespace configuration. If the default bean definition that is created by the namespace config must be extended somehow, this bean has to be manually re-configured, which can be very tedious and error prone.

    I'm not sure what a simple way could be to just define additional Voters that are added to the accessDecisionManager that is created by the namespace config.



    Best regards,
    James

  • #2
    The problem with adding lots of bells and whistles to the namespace is that it then becomes just as complex as the standard bean configuration. If you need to modify the namespace only slightly refer to the FAQ.

    Comment


    • #3
      I agree. On the other hand it's always very hard for a user to find out what the namespace config actually does and how to create a standard bean config with the desired changes applied. And the most common use cases should be supported I think.

      I'll try the approach with the BeanPostProcessor which sounds quite reasonable.

      Comment


      • #4
        PHP Code:
        /**
         * This BeanPostProcessor adds all {@link AccessDecisionVoter}s that are set with
         * {@link #setAdditionalAccessDecisionVoters(List)} to beans that are instances of {@link AffirmativeBased}. This is the
         * default {@link AccessDecisionManager} implementation that the spring security namespace handler creates.
         * <p>
         * 
         * The configuration could look like:
         * 
         * <pre>
         * {@code
         * <bean id="voterAdder" class="net.junisphere.eranger.test.security.VoterAdder">
         *     <property name="additionalAccessDecisionVoters">
         *         <list>
         *             <bean class="net.junisphere.eranger.security.internal.SystemRoleVoter" />
         *         </list> 
         *     </property>
         * </bean>
         * }
         * </pre>
         */
        @Component
        public class VoterAdder implements BeanPostProcessor {
            private List<
        AccessDecisionVoteradditionalAccessDecisionVoters;

            public 
        void setAdditionalAccessDecisionVoters(List<AccessDecisionVoteradditionalAccessDecisionVoters) {
                
        this.additionalAccessDecisionVoters additionalAccessDecisionVoters;
            }

            @
        Override
            
        public Object postProcessBeforeInitialization(Object beanString beanNamethrows BeansException {
                return 
        bean;
            }

            @
        Override
            
        public Object postProcessAfterInitialization(Object beanString beanNamethrows BeansException {
                if (
        bean instanceof AffirmativeBased) {
                    
        AffirmativeBased dm = (AffirmativeBasedbean;
                    
        additionalAccessDecisionVoters.addAll(dm.getDecisionVoters());
                    
        dm.setDecisionVoters(additionalAccessDecisionVoters);
                }
                return 
        bean;
            }

        Maybe this is of use for someone else.


        Best regards,
        James

        Comment

        Working...
        X