Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have spring security context in child context

I'm trying to have spring security context in child context, so I could have url security on the servlet context file.

I have:

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

on web.xml, general security configuration on spring-security.xml and

<!-- 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"/>

on the myapp-soap-servlet.xml. It doesn't work but fails with

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

However, if I move <security:http> part to spring-security root context configuration, everything works. Shouldn't it work the way I try? How can I get url-based security in my child context?

I also tried combining the context files into one, but the same problem seems to occur.

like image 715
eis Avatar asked Jun 04 '13 14:06

eis


1 Answers

The DelegatingFilterProxy will by default look in the root ApplicationContext which means by default you need to place your <http> configuration there (it is what creates the springSecurityFilterChain).

However, you can specify use that DelegatingFilterProxy a different ApplicationContext by specifying the contextAttribute for it to use. To do this update your web.xml as shown below

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

A similar example using Spring Security 3.2+'s AbstractSecurityWebApplicationInitializer can be seen below:

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";
    }

}

This works because it modifies the name of the ServletContext attribute that DelegatingFilterProxy uses to lookup the ApplicationContext. Instead of using the default value which discovers the root ApplicationContext it now uses the attribute that your MessageDispatcherServlet is using (thus pointing to the child context).

Note that MessageDispatcherServlet's (or any subclass of FrameworkServlet such as DispatcherServlet) stores the ApplicationContext in the ServletContext using the attribute name "org.springframework.web.servlet.FrameworkServlet.CONTEXT." + <servlet-name> where <servlet-name> is the name of the servlet. So in this instance, the attribute that must be configured is org.springframework.web.servlet.FrameworkServlet.CONTEXT.myapp-soap. If you changed the servlet-name from myapp-soap to spring-servlet, then you would use org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring-servlet instead.

PS I think the subject should read "How to have spring security context as child context"

like image 54
Rob Winch Avatar answered Oct 11 '22 11:10

Rob Winch