8

我正在尝试在子上下文中使用弹簧安全上下文,因此我可以在 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 根上下文配置,则一切正常。它不应该像我尝试的那样工作吗?如何在我的子上下文中获得基于 url 的安全性?

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

4

2 回答 2

17

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

但是,您可以通过指定要使用的DelegatingFilterProxycontextAttributeApplicationContext来指定使用它。为此,请更新您的 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. ApplicationContext它现在使用您正在使用的属性MessageDispatcherServlet(因此指向子上下文),而不是使用发现根的默认值。

请注意, 's(或诸如 的MessageDispatcherServlet任何子类)使用属性名称存储servlet的名称。所以在这种情况下,必须配置的属性是. 如果您将 servlet-name 更改为,那么您将使用它。FrameworkServletDispatcherServletApplicationContextServletContext"org.springframework.web.servlet.FrameworkServlet.CONTEXT." + <servlet-name><servlet-name>org.springframework.web.servlet.FrameworkServlet.CONTEXT.myapp-soapfrom myapp-soapspring-servletorg.springframework.web.servlet.FrameworkServlet.CONTEXT.spring-servlet

PS我认为主题应该阅读“如何将弹簧安全上下文作为子上下文”

于 2013-06-04T18:51:06.160 回答
2

<security:http>将不得不转到主应用程序上下文而不是子(servlet)上下文,因为这个安全命名空间元素创建了bean,它在主上下文中springSecurityFilterChain查找。DelegatingFilterProxy正如其 javadoc 明确指出的那样:

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

于 2013-06-04T17:45:45.243 回答