如何在子上下文中使用spring安全上下文

时间:2013-06-04 14:18:38

标签: spring spring-security jboss7.x spring-ws

我正在尝试在子上下文中使用spring安全上下文,因此我可以在servlet上下文文件中使用url安全性。

我有:

  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:/spring-security.xml
    </param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>myapp-soap</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
      <param-name>transformWsdlLocations</param-name>
      <param-value>true</param-value>
    </init-param>
  </servlet>

在web.xml上,spring-security.xml上的一般安全配置和

<!-- Authorization configurations -->
<security:http auto-config="false" use-expressions="true"
    create-session="never"
    authentication-manager-ref="authenticationManager"
    entry-point-ref="authenticationEntryPoint">

    <security:custom-filter
        position="PRE_AUTH_FILTER" ref="serviceAuthenticationFilter"/>

    <security:intercept-url
        pattern="/GetForbiddenUrl" access="hasRole('roleThatDoesntExist')" />
    <security:intercept-url pattern="/**" access="permitAll" />
</security:http>
<!-- annotation security -->
<security:global-method-security pre-post-annotations="enabled"/>

在myapp-soap-servlet.xml上。它无效但

失败
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/my-app/v1/soap]] (ServerService Thread Pool -- 192) JBWEB000284: Exception starting filter springSecurityFilterChain:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined

但是,如果我将<security:http>部分移动到spring-security root context配置,那么一切正常。它不应该像我尝试的那样工作吗?如何在我的子环境中获得基于URL的安全性?

我也尝试将上下文文件合并为一个,但似乎也出现了同样的问题。

2 个答案:

答案 0 :(得分:17)

DelegatingFilterProxy默认情况下会查看根ApplicationContext,这意味着默认情况下你需要在那里放置<http>配置(这是创建springSecurityFilterChain的原因)。

但是,您可以通过指定要使用的contextAttribute来指定使用DelegatingFilterProxy不同的ApplicationContext。为此,请更新您的web.xml,如下所示

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>contextAttribute</param-name>
        <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.myapp-soap</param-value>
    </init-param>
</filter>

使用Spring Security 3.2 +的AbstractSecurityWebApplicationInitializer的类似示例如下所示:

public class SecurityApplicationInitializer extends
        AbstractSecurityWebApplicationInitializer {

    @Override
    protected String getDispatcherWebApplicationContextSuffix() {
        // NOTE: if you are using AbstractDispatcherServletInitializer or
        // AbstractAnnotationConfigDispatcherServletInitializer You probably
        // want this value to be "dispatcher"
        return "myapp-soap";
    }

}

这是有效的,因为它修改了DelegatingFilterProxy用于查找ApplicationContext的ServletContext属性的名称。它不使用发现根ApplicationContext的默认值,而是使用MessageDispatcherServlet正在使用的属性(因此指向子上下文)。

请注意,MessageDispatcherServlet(或FrameworkServlet的任何子类,例如DispatcherServlet)使用属性名称{{ApplicationContextServletContext存储在"org.springframework.web.servlet.FrameworkServlet.CONTEXT." + <servlet-name>中1}}其中<servlet-name>是servlet的名称。因此,在此实例中,必须配置的属性为org.springframework.web.servlet.FrameworkServlet.CONTEXT.myapp-soap。如果您将servlet-name from myapp-soap更改为spring-servlet,那么您将改为使用org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring-servlet

PS我认为主题应该是“如何将春天的安全背景作为儿童背景”

答案 1 :(得分:2)

<security:http>必须转到主应用程序上下文而不是子(servlet)上下文,因为此安全命名空间元素创建springSecurityFilterChain bean,由DelegatingFilterProxy查找在主要背景下。正如其javadoc明确指出:

  

web.xml通常包含DelegatingFilterProxy定义,指定的filter-name对应于Spring的根应用程序上下文中的bean名称。