Question

I'm trying to add some intercept-method in my application (using spring security) without namespaces.

So here is what I did:
First, I added a filter to filter-chain-map named "methodSecurityInterceptor" as you can see:

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <security:filter-chain-map path-type="ant">
        <sec:filter-chain pattern="/css/**" filters="none" />
        <sec:filter-chain pattern="/images/**" filters="none" />
        <sec:filter-chain pattern="/login.jsp*" filters="none" />
        <sec:filter-chain pattern="/**"
            filters="
        ConcurrentSessionFilter,
        securityContextPersistenceFilter,
        sessionManagementFilter,
        authenticationProcessingFilter,
        exceptionTranslationFilter,
        filterSecurityInterceptor,
        methodSecurityInterceptor,
        logoutFilter" />
    </security:filter-chain-map>
</bean>



Then I introduced its bean like this:

<bean id="methodSecurityInterceptor"
class="org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="accessDecisionManager" ref="accessDecisionManager" />
    <property name="securityMetadataSource" ref="MyMethodMetdataSource">

    </property>
</bean> 

<bean id="MyMethodMetdataSource" class="com.datx.dao.MyMethodMetdataSource">
</bean>


And I have my MyMethodMetadataSource implemented like this:

public class MyMethodMetdataSource extends AbstractMethodSecurityMetadataSource{

@Override
public Collection<ConfigAttribute> getAttributes(Method arg0, Class<?> arg1) {

    String url = arg0.getName();
    List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();

    attributes = getAttributesByURL2(url); //Here is my function which
                                           //returns corresponding roles

    return attributes;
}
    @Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
    // TODO Auto-generated method stub
    return null;
}


Apparently I am not allowed to use methodSecurityInterceptor as it's not a filter!
So what should I do?
I've read this but I have no idea how to use it with one of Spring AOP's proxying mechanisms!

So... Any idea?

Was it helpful?

Solution

The example I gave you before, is pretty much as simple as you can make it without using the namespace <global-method-security> element.

Use Spring's AOP namespace with a pointcut matching the method(s) you want to protect:

<aop:config>
  <aop:pointcut id='targetMethods' expression='execution(* org.springframework.security.TargetObject.*(..))'/>
  <aop:advisor advice-ref='securityInterceptor' pointcut-ref='targetMethods' />
</aop:config>

and declare the security interceptor as a bean:

<bean id='target' class='org.springframework.security.TargetObject'/>
<bean id='securityInterceptor' class='org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor' autowire='byType' >
   <property name='securityMetadataSource' ref="yourSecurityMetadataSource"/>
</bean>

External calls to that bean will then be routed through the security interceptor before the method is invoked.

I'd suggest you checkout the source and try running the test in a debugger to get a feel for how it works if you haven't use AOP before.

OTHER TIPS

Luckily I found the answer to this question.
One cannot use filters for intercept-method. So I suggest using proxies instead.

So here is the solution:
Change back the filter chain to its normal:

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
    <sec:filter-chain pattern="/css/**" filters="none" />
    <sec:filter-chain pattern="/images/**" filters="none" />
    <sec:filter-chain pattern="/login.jsp*" filters="none" />
    <sec:filter-chain pattern="/**"
        filters="
    ConcurrentSessionFilter,
    securityContextPersistenceFilter,
    sessionManagementFilter,
    authenticationProcessingFilter,
    exceptionTranslationFilter,
    filterSecurityInterceptor,
    logoutFilter" />
</security:filter-chain-map>


See what I did there? I removed the methodSecurityInterceptor.

Then add a proxy:

<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="interceptorNames">
        <list>
            <value>methodSecurityInterceptor</value> <!-- Responsible for checking roles and accesspaths -->
        </list>
    </property>
    <property name="beanNames">
        <list>
            <value>Manager2</value> <!--The Class that I want to protect its methods -->
        </list>
    </property>
</bean>


Of course we have to add these beans to application context too:

<bean id="methodSecurityInterceptor"
    class="org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="accessDecisionManager" ref="accessDecisionManager" />
        <property name="securityMetadataSource" ref="MyMethodMetdataSource">            
        </property>
    </bean>
<bean id="MyMethodMetdataSource" class="com.datx.dao.MyMethodMetdataSource">
</bean>


Here we go :)

Now every method in Manager2.java will be checked for every method call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top