如何使用其过滤器而不是名称空间使用拦截方法?

时间:2012-07-01 13:18:40

标签: spring spring-security intercept

我正在尝试在我的应用程序中添加一些拦截方法(使用spring security)而没有名称空间。

所以这就是我所做的:
首先,我在过滤链映射中添加了一个名为“methodSecurityInterceptor”的过滤器,如下所示:

<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>



然后我像这样介绍了它的bean:

<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>


我的MyMethodMetadataSource实现如下:

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;
}


显然我不允许使用 methodSecurityInterceptor ,因为它不是过滤器!
那我该怎么办? 我已阅读this但我不知道如何将其与Spring AOP的代理机制之一一起使用

所以...任何想法?

2 个答案:

答案 0 :(得分:2)

example I gave you before,非常简单,只需在不使用命名空间<global-method-security>元素的情况下完成。

使用Spring AOP namespace的切入点与您要保护的方法匹配:

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

并将安全拦截器声明为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>

在调用该方法之前,将通过安全拦截器路由对该bean的外部调用。

我建议您检查源代码并尝试在调试器中运行测试,以了解如果之前没有使用AOP,它是如何工作的。

答案 1 :(得分:1)

幸运的是,我找到了这个问题的答案。
人们不能使用过滤器来拦截方法。所以我建议改用代理。

所以这是解决方案:
将过滤器链更改为正常:

<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>


看看我在那里做了什么?我删除了methodSecurityInterceptor
然后添加代理:

<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>


当然,我们也必须将这些bean添加到应用程序上下文中:

<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>


我们走了:)

现在,每次方法调用都会检查Manager2.java中的每个方法。