【问题标题】:How to have spring security context in child context如何在子上下文中拥有弹簧安全上下文
【发布时间】:2013-06-04 14:18:38
【问题描述】:

我正在尝试在子上下文中使用 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

但是,如果我将 &lt;security:http&gt; 部分移动到 spring-security 根上下文配置,一切正常。它不应该像我尝试的那样工作吗?如何在我的子上下文中获得基于 url 的安全性?

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

【问题讨论】:

  • 你确定你的spring-security.xml是被spring捡到的吗?
  • @MaksymDemidas 是的,因为移动 http 部分会导致在父上下文和子上下文中使用所有指令

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


【解决方案1】:

默认情况下,DelegatingFilterProxy 将在根 ApplicationContext 中查找,这意味着默认情况下您需要将 &lt;http&gt; 配置放在那里(它是创建 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)使用属性名称"org.springframework.web.servlet.FrameworkServlet.CONTEXT." + &lt;servlet-name&gt;ApplicationContext 存储在ServletContext 中,其中&lt;servlet-name&gt; 是小服务程序。所以在这种情况下,必须配置的属性是org.springframework.web.servlet.FrameworkServlet.CONTEXT.myapp-soap。如果您将 servlet 名称 from myapp-soap 更改为 spring-servlet,那么您将改用 org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring-servlet

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-10-22
      • 1970-01-01
      • 2020-01-10
      • 2014-05-31
      • 2018-05-06
      • 2019-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多