【问题标题】:How can I use intercept-method using its filters, not namespace?我如何使用拦截方法使用它的过滤器,而不是命名空间?
【发布时间】:2012-07-01 13:18:40
【问题描述】:

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

所以这就是我所做的:
首先,我在 filter-chain-map 中添加了一个名为“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 的代理机制之一一起使用

所以...有什么想法吗?

【问题讨论】:

  • 这看起来和我昨天给你的答案的内容很相似。您是否删除了之前的问题?我还为您提供了 Spring Security 代码库中使用 AOP 的示例的指针。你试过用那个吗?方法安全与 Web 过滤器无关。
  • 是的,谢谢。我已阅读您的答案,我认为应该以这种方式提出问题。顺便说一句,我不明白如何使用 AOP。这有点模糊。你能举个很简单的例子吗?

标签: spring spring-security intercept


【解决方案1】:

example I gave you before, 非常简单,无需使用命名空间 &lt;global-method-security&gt; 元素。

使用 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,我建议您检查源代码并尝试在调试器中运行测试,以了解它是如何工作的。

【讨论】:

  • 谢谢卢克,你的建议很好,对我帮助很大。幸运的是,我找到了我正在寻找的解决方案,并在这里写出来供其他人使用。
  • 这个答案是对的,和我的差不多。我已经使用代理写了我对这个问题的回答。如果你有兴趣,也可以看看。
  • 顺便说一句,我不明白我应该在哪里声明我的班级是安全的!你能给我解释一下吗?考虑我的班级名称是 myPackage.Manager2
  • 这就是切入点的作用。这是一个 AspectJ 风格的表达式,定义了应该保护哪些方法。
  • 那么,我怎样才能只声明一个要保护的类呢?我看不到一个类被声明为安全的。您建议的代码是否保护所有类?
【解决方案2】:

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

所以这是解决方案:
将过滤器链改回正常状态:

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


看看我在那里做了什么?我删除了方法SecurityInterceptor。

然后添加一个代理:

<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 中的每个方法都会被检查每个方法调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    相关资源
    最近更新 更多