【问题标题】:AOP MethodSecurityInterceptor not getting invoked in Spring SecurityAOP MethodSecurityInterceptor 没有在 Spring Security 中被调用
【发布时间】:2012-07-27 18:40:06
【问题描述】:

我使用的是 Spring Security 3.0.7,我的应用程序部署在 JBOSS 上。

我正在为我的应用程序设置 org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor 以添加对服务层中某些方法的调用的限制。但由于某种原因,拦截器没有被调用,我能够从具有角色 ROLE_USER 的用户调用所有方法。 我的 security.xml 看起来像这样:

<security:http auto-config='true' authentication-manager-ref="authenticationManager" use-expressions="true" request-matcher="ant" create-session="always"
    entry-point-ref="authenticationEntryPoint" >

    <security:intercept-url pattern="/login.jsp" access="permitAll" />
    <security:intercept-url pattern="/configure/" access="hasRole('ROLE_ADMIN')"  />
    <security:intercept-url pattern="/**" access="isAuthenticated()" />

    <security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=Authentication Failed!" default-target-url="/landing.do" 
    always-use-default-target="true"  />

    <security:logout invalidate-session="true" delete-cookies="true" />


    <security:session-management>
        <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login.jsp"/>
    </security:session-management>    
</security:http>

<security:method-security-metadata-source id="securityMetadataSource">
        <security:protect method="com.services.CreateUserService.createUser" access="ROLE_ADMIN"/>
        <security:protect method="com.services.DeleteUser.deleteUser" access="ROLE_ADMIN"/>
</security:method-security-metadata-source>

<security:global-method-security authentication-manager-ref="authenticationManager" access-decision-manager-ref="accessDecisionManager" 
metadata-source-ref="securityMetadataSource" pre-post-annotations="disabled" secured-annotations="disabled" />

<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <property name="loginFormUrl" value="/login.jsp"/>
</bean>

<bean id="myRoleVoter" class="com.interceptors.MyRoleVoter" />

<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager" >
    <property name="providers">
        <list>
            <ref local="daoAuthenticationProvider"/>
        </list>
    </property>
</bean> 

<bean id="accessDecisionManager" class="com.interceptors.MyAccessDecisionManager"  p:allowIfAllAbstainDecisions="false" >
    <property name="decisionVoters">
        <list>
            <ref local="myRoleVoter"/>
        </list>
    </property> 
</bean>


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

身份验证部分工作得非常好。但是,我的 MethodSecurityInterceptor 从未被调用过,因此我的 AccessDecisionManager 或 RoleVoter 也不会被调用。

如果我在第一行添加我的 accessDecisionManager 的引用,那么我的身份验证层将停止工作。所有请求都以匿名用户身份传递给 AccessDecisionManager。

<security:http security="none" pattern="/login.jsp" />

<security:http auto-config='true' authentication-manager-ref="authenticationManager" access-decision-manager-ref="accessDecisionManager" use-expressions="true" request-matcher="ant" create-session="always"
    entry-point-ref="authenticationEntryPoint" >

我知道我缺少一些 TINY 配置,但我无法在文档中的任何地方找到该配置。

【问题讨论】:

    标签: spring spring-security spring-aop


    【解决方案1】:

    您可能已经在应用程序根上下文中声明了 MethodSecurityInterceptor,并希望它适用于 servlet 上下文中的 bean。

    如果您希望global-method-security 在 servlet 上下文中工作,您应该在 servlet xml 配置中显式声明它。

    在错误的上下文中声明 AOP 拦截器是一个非常常见的错误,因此请检查您的服务层 bean 是否没有在 servlet 上下文中创建(例如通过自动扫描)。

    【讨论】:

      【解决方案2】:

      我已经找到了解决方案。我必须定义两个身份验证管理器和一个访问决策管理器。一个身份验证管理器进入我的根上下文,全局方法安全性将使用它来创建表单登录身份验证机制。

      另一个身份验证管理器和访问决策管理器进入服务上下文,它将用于创建我的自定义方法安全拦截器。

      applicationContext-Security.xml

      <!-- The authentication manager responsible for authenticating the users -->
      <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager" >
          <property name="providers">
              <list>
                  <ref local="daoAuthenticationProvider"/>
              </list>
          </property>
      </bean> 
      

      服务的上下文文件。 service.security.xml

          <!--we need a separate authentication manager for method security -->
          <bean id="methodAuthenticationManager" class="org.springframework.security.authentication.ProviderManager" >
              <property name="providers">
                  <list>
                      <ref local="daoAuthenticationProvider"/>
                  </list>
              </property>
          </bean> 
      
          <!--we need a separate accessDecisionManager for method security -->
          <bean id="methodAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased" >
              <property name="decisionVoters">
                  <list>
                      <ref local="myRoleVoter"/> <!-- the voter will decide weather methodInvocation is allowed or not -->
                  </list>
              </property> 
          </bean>
      
          <!-- The Method Security Interceptor to intercept all the calls to methods -->
          <bean id="methodSecurityInterceptor" class="org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
              <property name="authenticationManager" ref="methodAuthenticationManager"/>
              <property name="accessDecisionManager" ref="methodAccessDecisionManager"/>
              <property name="securityMetadataSource" ref="swiftSecurityMethodMetadataSource" />
          </bean>
      
      
      <security:method-security-metadata-source id="securityMetadataSource">
          <security:protect method="fullyQualifiedMethod" access="Administrator"/>
      </security:method-security-metadata-source>
      
      <security:global-method-security authentication-manager-ref="methodAuthenticationManager" access-decision-manager-ref="methodAccessDecisionManager" 
          metadata-source-ref="swiftSecurityMethodMetadataSource" jsr250-annotations="disabled" secured-annotations="disabled"/>
      

      【讨论】:

        【解决方案3】:

        不调用 AOP MethodSecurityInterceptor 的另一个常见原因 - 您错过了 cglib 或类似的字节码操作。

        所以只使用了java.lang.reflect.Proxy,因此无法代理private方法!只需将 @Secured 方法公开 - 一切都会好起来的!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-01-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-12
          • 2013-10-23
          • 2012-07-06
          相关资源
          最近更新 更多