Get Spring Security intercept urls from database or properties

12,741

Solution 1

It's been a while, but you can create a Voter object which helps decide whether to allow access to a URL. The Voter object can load data from the database, or a file, or just randomly return Allow, Deny, or Abstain.

Solution 2

do you want to use something like this in you spring xml?

<!-- Settings -->
<b:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <b:property name="locations">
        <b:value>/WEB-INF/config.properties</b:value>
    </b:property>
</b:bean>

and then als in your Spring XML:

<http entry-point-ref="authenticationProcessingFilterEntryPoint">
        <intercept-url pattern='/custom/**' access="${roles.admin}"/>
</http>
Share:
12,741
Droo
Author by

Droo

Updated on June 27, 2022

Comments

  • Droo
    Droo almost 2 years

    Hopefully this is super simple, exists, and I'm overlooking something right under my nose. I know that I can restrict access via annotations:

    @Secured({"ROLE_ADMIN"})
    

    or via config:

    <security:intercept-url pattern="/**" access="ROLE_USER, ROLE_ADMIN, ROLE_SUPER_USER" />
    

    I would prefer to obtain authentication rules from a database, something like:

    <security:intercept-url provider="authProvider"/>
    
    <bean id="authProvider" class="AuthProviderImpl">
        <property name="userDetailsService" ref="userDetailsService"/>
    </bean>
    

    Worst case scenario, there has to be a way to populate via a properties file right?...

    /admin/**=ROLE_ADMIN
    /**=ROLE_USER

    <security:intercept-url props="classpath:urls.properties"/>
    

    etc.

    Please tell me this exists or my brain will explode!!! The Grails spring-security plugin ships with this out of the box so I know this has to exist. Please don't let my brain explode!!!

    EDIT:

    Figured it out...

    You have to provide a custom org.springframework.security.intercept.web.FilterSecurityInterceptor and provide the objectDefinitionSource:

    <bean id="filterSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
        <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" />
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="accessDecisionManager" ref="accessDecisionManager" />
        <property name="objectDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /**login.html=IS_AUTHENTICATED_ANONYMOUSLY
                /user/**=ROLE_ADMIN
            </value>
        </property>
    </bean>
    

    And I think I'm going to use a FactoryBean:

    public class RequestMappingFactoryBean implements FactoryBean {
    
        private final static String EOL = System.getProperty("line.separator");
    
        public Object getObject() throws Exception {
            StringBuffer sb = new StringBuffer();
            sb.append("CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON");
            sb.append(EOL);
            sb.append("PATTERN_TYPE_APACHE_ANT");
            sb.append(EOL);
            sb.append("/**login.html=IS_AUTHENTICATED_ANONYMOUSLY");
            sb.append(EOL);
            sb.append("/user/**=ROLE_ADMIN");
            return sb.toString();
        }
    
        @SuppressWarnings("unchecked")
        public Class getObjectType() {
            return String.class;
        }
    
        public boolean isSingleton() {
            return true;
        }
    
    }
    

    Pass it a DAO, etc.

    <bean id="filterSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
        <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" />
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="accessDecisionManager" ref="accessDecisionManager" />
        <property name="objectDefinitionSource" ref="requestMappings" />
    </bean>
    
    <bean id="requestMappings" class="RequestMappingFactoryBean" />