Igor Artamonov
Igor Artamonov

Reputation: 35961

Two separate Spring contexts for one webapp

I want to use two different Spring web contexts, each have own contextConfig, spring servlet and filter, that should be mapped to different urls. I have a

  1. Standard Grails project, mapped to '/'
  2. And an existing Spring webapp, that I want to map to /extra/

I know that I can deploy both into one Tomcat, but I'm looking for a way of making one app (one war, etc), because It can simplify our deployment and development process.

This applications don't need to share beans or anything, should be completely separate. Both have DispatcherServlet and DispatcherFilter (and both are using Spring Security, but different configuration)

How I can configure web.xml for such webapp?

I've tried to add new filter:

<filter>
    <filter-name>extraSpringSecurityFilterChain</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.extraSpring</param-value>
    </init-param>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>extraSecurityFilterBean</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>extraSpringSecurityFilterChain</filter-name>
    <url-pattern>/extra/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

and spring dispatcher servlet:

<servlet>
    <servlet-name>extraSpring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
        <param-name>springConfigLocation</param-name>
        <param-value>classpath:extra-spring-web.xml</param-value>
    </init-param>
</servlet>

Where:

It's semi-working now:

So, the question, how I can define context for DelegatingFilterProxy? I even tried to add this files into main context (contextConfigLocation param), it's not what i'm looking for, but it didn't work.

I've taken a look into DelegatingFilterProxy sources, but it's not clear for me how it loads the context.

Upvotes: 8

Views: 4243

Answers (3)

Gergely Szilagyi
Gergely Szilagyi

Reputation: 3903

If the modules are completely separate: the easiest way is to package them as two different webapp. Tens of different spring-based apps can run in one appserver -even on a modest developer machine- without issues.

Upvotes: 1

Ian Roberts
Ian Roberts

Reputation: 122364

As per my comment on the question, if the security filter chain is defined in extra-spring-security.xml then you need to ensure that that file is loaded by your extra DispatcherServlet in addition to extra-spring-web.xml either by <import>ing the -security file from the -web one or configuring it as:

<servlet>
    <servlet-name>extraSpring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
          classpath:extra-spring-web.xml
          classpath:extra-spring-security.xml
        </param-value>
    </init-param>
</servlet>

You will also need to ensure that the security filter in the Grails application doesn't apply to /extra URIs, exactly how you do this depends on whether you're using annotations, database RequestMap entries etc.

Upvotes: 3

Rob Winch
Rob Winch

Reputation: 21720

A few questions

  • What does your Spring Security configuration look like?
  • I'm confused why the error states "No bean named 'apiservSecurityFilterChain' is defined" but the web.xml you have posted only references extraSpringSecurityFilterChain (the bean names should match or some important configuration is being left out).

Possible Answer

I'm guessing the problem is that the filter-name needs to match Spring Security's bean name (cannot know for sure without seeing the Spring Security configuration you are using). The default value used by the Spring Security namespace is springSecurityFilterChain, so try the following in the web.xml instead (notice extraSpringSecurityFilterChain changed to springSecurityFilterChain):

<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.extraSpring</param-value>
    </init-param>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>extraSecurityFilterBean</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/extra/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Upvotes: 0

Related Questions