I'm trying to understand the reccommended way for defining Spring Security in Spring-MVC applications, where the bean definitions is split across multiple parent/child contexts.
For example, my current app's web.xml
looks as follows, (which I understand to be fairly standard)
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
/WEB-INF/securityContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
So, I have a standard ContextLoaderListener
defined at /
, which loads my global configs - applicationContext.xml
and securityContext.xml
.
I also define the spring mvc DispatcherServlet
at /app/
, which loads it's own beans from spring-mvc-servlet.xml
.
As I understand it, config defined in spring-mvc-servlet.xml
is not visible to config defined in either of the top-level context files.
Where then is the best place to define app-level security concepts? For example, I'd like to add the following filter.
<security:http pattern="/oauth/token" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint">
<security:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
</security:http>
This is so that requests to /app/oauth/token
pass through this filter, and get basic authentication processed.
Because this pertains directly to a concern of the Spring-MVC app, I initially defined it in spring-mvc-context.xml
(which is why the app
is excluded from the url).
However, this means it's not visible to the security config defined in securityContext.xml
, so it's ignored.
So, I move it up to securityContext.xml
, but in doing so, also must move all the dependencies.
I quickly end up moving everything up to applicationContext.xml
, which leaves the spring-mvc-context.xml
almost empty.
Is this common? What is the reccomended split between what is defined in top-level contexts, and what gets defined in child contexts?
Given that spring-mvc defines a series of controllers, which I want to mark as @Secured
, how will these be processed if the controller is not visible to the security context?
Do I need to move my <mvc:annotation-driven />
from the servlet.xml
to the global applicationContext.xml
?
Do I need additional configuration within the spring-mvc-servlet.xml
to tell it to participate in Spring security?
I've read the documentation on Spring-MVC, but there's very few specifics on how to configure this. Additionally, the Spring OAuth examples seem to define everything within a single config file, which doesn't seem very real-world, and seems to contradict other examples I've read.
First: the beans defined within applicationContext.xml
(ContextLoaderListener
) can not access the one defined in spring-mvc-servlet.xml
(DispatcherServlet
) but not the other way around.
You asked:
Given that spring-mvc defines a series of controllers, which I want to mark as @Secured, how will these be processed if the controller is not visible to the security context?
So this works without problems, because the controllers must be defined in the spring-mvc-servlet.xml
, so they "see" the Spring Security stuff defined in applicationContext.xml
Do I need to move my from the servlet.xml to the global applicationContext.xml?
No
Do I need additional configuration within the spring-mvc-servlet.xml to tell it to participate in Spring security?
No
... which leaves the spring-mvc-context.xml almost empty. Is this common?
The spring-mvc-context.xml
should contain every thing that is related to Web Stuff (except secrutiy). So the common parts of the spring-mvc-context.xml
are component scan for @Controller
, some Interceptors (mvc:interceptors
), mvc:resources
, mvc:default-servlet-handler
, mvc:view-controller
, ReloadableResourceBundleMessageSource
, CookieLocaleResolver
, .SimpleMappingExceptionResolver
...
BTW: If you use component scan, then you need two of them, one at applicationContext.xml
to scan for @Service
@Repository
and @Component
(But not @Controller
) and a second in spring-mvc-context.xml
that only scan for @Controller
!
@See also this question: ContextLoaderListener or not? It discuss the theme from an other point of view.
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