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.
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With