Can I have multiple security contexts with spring security?

java, spring, spring-security

Solution

It has been tricky to do until recently, but now it is easy!

Spring Security has added support for the scenario in version 3.1. It is currently available as a Release Candidate, implemented by SEC-1171. Details of the syntax are in the manual included with 3.1.

It's pretty simple to use. Basically you just define multiple `http` elements in your Spring Security configuration, one for each context. We're using it like this:

<!-- Configure realm for system administration users -->
<security:http pattern="/admin/**" create-session="stateless">
    <security:intercept-url pattern='/**' access='ROLE_ADMIN' requires-channel="https" />
    <security:custom-filter position="PRE_AUTH_FILTER" ref="preAuthFilter" />
</security:http>


<!-- Configure realm for standard users -->
<security:http auto-config="true" access-denied-page="/error/noaccess" use-expressions="true" create-session="ifRequired">
    <security:form-login 
            ...
            ...
</security:http>

The key thing to note is the `pattern="/admin/**"` on the first `http` element. This tells Spring that all URLs under `/admin` are subject to that context instead of the default context — and thus URLs under `/admin` use your preauthorisation filter instead.

Problem

I have one security context definition that uses PreAuthenticatedProcessingFilterEntryPoint for the flex part of my application. How can I have another definition that will use standard form login with html forms for another part of my application? Here's what I currently have: ``` <?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd"> <http auto-config="true" access-denied-page="/admin/access-denied"> <intercept-url pattern="/admin/login*" filters="none"/> <intercept-url pattern="/admin/access-denied" filters="none"/> <intercept-url pattern="/admin/**/*" access="ROLE_ADMIN" /> <form-login login-page="/admin/login" authentication-failure-url="/admin/login?login_error=1" default-target-url="/admin/index" login-processing-url="/admin/login-process"/> <logout logout-success-url="/admin/login"/> </http> <global-method-security jsr250-annotations="enabled" /> <beans:bean id="preAuthenticatedEntryPoint" class="org.springframework.security.ui.preauth.PreAuthenticatedProcessingFilterEntryPoint" > </beans:bean> <beans:bean id="userAccountManager" class="com.mycomp.service.managers.jpa.UserAccountJpaManager" /> <beans:bean id="userService" class="com.mycomp.auth.DefaultUserDetailsService" /> <beans:bean id="defaultPasswordEncoder" class="com.mycomp.auth.DefaultPasswordEncoder" /> <authentication-provider user-service-ref="userService"> <password-encoder ref="defaultPasswordEncoder"/> </authentication-provider> </beans:beans> ``` What I'd like to do is use another authentication provider for the urls that are in the admin site, the one I currently have is for the flex application. So I want the security for the admin urls to use another userDetailsService bean.

Original source