Results 1 to 4 of 4

Thread: How to add voters to the default accessDecisionManager?

  1. #1
    Join Date
    Oct 2006
    Location
    Zürich
    Posts
    101

    Default 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. #2
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    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.
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  3. #3
    Join Date
    Oct 2006
    Location
    Zürich
    Posts
    101

    Default

    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.

  4. #4
    Join Date
    Oct 2006
    Location
    Zürich
    Posts
    101

    Lightbulb

    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •