Integrating Crowd with Spring Security
The content on this page relates to platforms which are not supported for Crowd. Consequently, Atlassian can not guarantee providing any support for the steps described on this page. Please be aware that this material is provided for your information only and that you use it at your own risk.
Crowd provides centralized authentication and single sign-on connectors for the web security framework Spring Security. Spring Security provides a modular and highly configurable approach to authentication and authorization for J2EE applications.
If your web application already makes use of the Spring Security framework for authentication and authorization, you can use the Crowd Spring Security connector to allow your application to easily delegate authentication and authorization requests to Crowd.
Spring, Acegi and Crowd versions
Spring Security was formerly known as Acegi. There is a separate tutorial for integrating Acegi with Crowd. The connector is developed and tested with Spring Security 3.1 from Crowd 2.5 and later. Please use a previous supported release of Crowd if you require compatibility with Spring Security 2.0.4.
Please consult the Spring Security suggested steps or reference guide for a thorough insight into the Spring Security framework. You might also find useful information in our Appfuse integration tutorial.
This guide assumes developer-level knowledge and a Spring Security-based web application
This guide is for developers rather than administrators. This guide assumes you have Crowd 2.5 or later installed and that you want to integrate your Spring Security-based web application with Crowd's security server. The documentation below describes how to integrate Crowd with your own application that uses the Spring Security framework. It assumes you already use Spring Security in your application. If you need help integrating the Spring Security framework with your web application, have look at some of the Spring Security documentation.
Prerequisites
- Download and configure Crowd. Refer to the Crowd Installation Guide for detailed information on how to do this. We will refer to the Crowd root folder as
CROWD
. - Have your Spring Security-based custom application ready for tweaking. We will refer to your custom application as 'SpringSecApp'.
Step 1. Configuring Crowd to Talk to your Spring Security Application
Crowd needs to be aware that SpringSecApp will be making authentication requests to Crowd. In brief, you will need to do the following:
- Add the SpringSecApp application to Crowd.
- Add and configure the directories visible to SpringSecApp.
- Add and map the groups which are allowed to authenticate with SpringSecApp.
Please see Adding an Application for a detailed guide.
Step 2. Installing the Crowd Spring Security Connector
2.1 Adding the Crowd Spring Security Connector to your Spring Security Application
You will need to add the Crowd Spring Security connector library and its associated dependencies to your Spring Security application. You can do this manually by copying over the JAR files to your Spring Security application or, if your Spring Security application is a Maven project, you can add the Crowd Spring Security connector as a project dependency. Both methods are described below.
2.1.1 Manually Adding the Crowd Spring Security Connector Libraries
Follow either 2.1.1 or 2.1.2 (not both).
Copy the Crowd integration libraries and configuration files. This is described in the Client Configuration documentation. You will need to copy at least the following file to your Spring Security application:
Copy From | Copy To |
---|---|
crowd-integration-springsecurity-X.X.X (this file is not included in the crowd distribution, you need to download it from packages.atlassian.com) | SpringSecApp/WEB-INF/lib |
CROWD/client/lib/*.jar | SpringSecApp/WEB-INF/lib |
2.1.2 Adding the Crowd Spring Security Connector as a Maven Dependency
Follow either 2.1.1 or 2.1.2 (not both).
Add to your pom.xml
:
<properties>
<crowd.version>2.5.0</crowd.version>
<spring.version>3.1.0.RELEASE</spring.version>
</properties>
<dependencies>
...
<dependency>
<groupId>com.atlassian.crowd</groupId>
<artifactId>crowd-integration-springsecurity</artifactId>
<version>${crowd.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Crowd needs at runtime -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
<scope>runtime</scope>
</dependency>
...
</dependencies>
Ensure you have dependencies on the spring-
modules to pick up the versions of Spring required by Crowd rather than the possibly lower version specified by Spring Security.
2.2 Adding the Cache Configuration File
Copy the following file into your application's classpath:
Copy From | Copy To |
---|---|
CROWD/client/conf/crowd-ehcache.xml | SpringSecApp/WEB-INF/classes/crowd-ehcache.xml |
This file can be tweaked to change the cache behavior.
2.3 Configuring the Crowd Spring Security Connector Properties
The Crowd Spring Security connector needs to be configured with the details of the Crowd server.
Copy the default
crowd.properties
file to the classpath of your Spring Security application:Copy From
Copy To
CROWD/client/conf/crowd.properties
SpringSecApp/WEB-INF/classes
Edit
crowd.properties
and populate the following fields appropriately:Key
Value
Same as application name defined when adding the application to Crowd in Step 1.
application.password
Same as application password defined when adding the application to Crowd in Step 1.
crowd.server.url
http://localhost:8095/crowd/services/
session.validationinterval
This is the time interval between requests which validate whether the user is logged in or out of the Crowd SSO server. Set to 0, if you want authentication checks to occur on each request. Otherwise set to the number of minutes you wish to wait between requests. Setting this value to 1 or higher will increase the performance of Crowd's integration.
You can read more about the crowd.properties file.
Step 3. Configuring your Spring Security Application to Use the Crowd Spring Security Connector
There are two ways you can integrate your application with Crowd:
- Centralized user management: The user repository available to your application will be the user repository allocated to your application via Crowd. This means that your application will use the centralized user repository for retrieving user details as well as performing authentication.
- Single sign-on: In addition to centralized authentication, SSO will be available to your application. If any other SSO-enabled applications (such as Jira, Confluence, or your own custom applications) are integrated with Crowd, then SSO behavior will be established across these applications. If you sign in to one application, you are signed in to all applications. If you sign out of one application, you are signed out of all applications.
First, you will need to add the Crowd client application context to wire up the Crowd beans that manage the communication to Crowd. You can do this by including the applicationContext-CrowdRestClient.xml
Spring configuration file, found in crowd-integration-client-rest.jar
. For example, if you are configuring Spring using a context listener, you can add the following parameter in your your Spring Security application's WEB-INF/web.xml
:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
...
classpath:/applicationContext-CrowdRestClient.xml
...
</param-value>
</context-param>
3.1 Configuring Centralized User Management
The following sections assume that you have the Spring Security schema mapped to the security
namespace. Perform the following updates to your Spring Security configuration:
Add the definition of the CrowdUserDetailsService:
<bean id="crowdUserDetailsService" class="com.atlassian.crowd.integration.springsecurity.user.CrowdUserDetailsServiceImpl"> <property name="crowdClient" ref="crowdClient"/> <property name="authorityPrefix" value="ROLE_"/> </bean>
Add the definition of the RemoteCrowdAuthenticationProvider:
<bean id="crowdAuthenticationProvider" class="com.atlassian.crowd.integration.springsecurity.RemoteCrowdAuthenticationProvider"> <constructor-arg ref="crowdClient"/> <constructor-arg ref="crowdHttpAuthenticator"/> <constructor-arg ref="crowdUserDetailsService"/> </bean>
Controlling granted authority names
Rather than taking the group name and setting a prefix, you can define a mapping to grant specific authorities when a user belongs to Crowd groups:
<util:map id="groupToAuthorityMappings">
<beans:entry key="crowd-administrators" value="ROLE_crowd-administrators" />
<beans:entry key="some-other-group" value="specific-authority-for-other-group" />
</util:map>
and then set it on the crowdUserDetailsService
:
<beans:bean id="crowdUserDetailsService" class="com.atlassian.crowd.integration.springsecurity.user.CrowdUserDetailsServiceImpl">
...
<beans:property name="groupToAuthorityMappings">
<beans:bean factory-bean="groupToAuthorityMappings" factory-method="entrySet" />
</beans:property>
Further extensions
- If you have an existing user data model, then you can extend or wrap the CrowdDetailsService to cater for user objects within your application domain.
- If you require users within Crowd to be created in your application's persistence model so that you can store application-specific user data, you can extend the CrowdAuthenticationProvider to create records for successfully authenticated Crowd users.
Crowd's remote API
We recommend that applications do not store the Crowd users locally. Rather, applications should query users via Crowd's remote API.
3.2 Configuring Single Sign-On (SSO)
SSO is optional and requires centralized user management
Single sign-on is optional. If you wish to configure SSO you must first configure centralized user management as described in step 3.1 above.
Perform the following additional updates to your Spring Security configuration:
- Remove defaults from the
<http/>
element:- Remove the
auto-config
attribute and add anentry-point-ref="crowdAuthenticationProcessingFilterEntryPoint"
attribute to the http element. Remove the
<form-login>
element.Include
custom-filter
s for login and logout.
You should end up withhttp
elements similar to this:<http pattern='/styles/*' security='none'/> <http pattern='/scripts/*' security='none'/> <http auto-config="false" entry-point-ref="crowdAuthenticationProcessingFilterEntryPoint"> <custom-filter position="FORM_LOGIN_FILTER" ref='authenticationProcessingFilter'/> <custom-filter position="LOGOUT_FILTER" ref='logoutFilter'/> <intercept-url pattern="/admin/*" access="ROLE_application-administrators"/> <intercept-url pattern="/passwordHint.html" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/> <intercept-url pattern="/**/*.html*" access="IS_AUTHENTICATED_FULLY"/> </http>
- Remove the
Change the default processing filter to Crowd's SSO filter by adding the following bean definitions:
<authentication-manager alias="authenticationManager"> <authentication-provider ref='crowdAuthenticationProvider' /> </authentication-manager> <beans:bean id="crowdAuthenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <beans:constructor-arg value="/login.jsp"/> </beans:bean> <beans:bean id="authenticationProcessingFilter" class="com.atlassian.crowd.integration.springsecurity.CrowdSSOAuthenticationProcessingFilter"> <beans:constructor-arg ref="tokenHelper"/> <beans:constructor-arg ref="crowdClient"/> <beans:constructor-arg ref="clientProperties"/> <beans:property name="httpAuthenticator" ref="crowdHttpAuthenticator"/> <beans:property name="authenticationManager" ref="authenticationManager"/> <beans:property name="filterProcessesUrl" value="/j_security_check"/> <beans:property name="authenticationFailureHandler"> <beans:bean class="com.atlassian.crowd.integration.springsecurity.UsernameStoringAuthenticationFailureHandler"> <beans:property name="defaultFailureUrl" value="/login.jsp?error=true"/> </beans:bean> </beans:property> <beans:property name="authenticationSuccessHandler"> <beans:bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <beans:property name="defaultTargetUrl" value="/"/> </beans:bean> </beans:property> </beans:bean>
Add the definition of the CrowdLogoutHandler and add in a LogoutFilter that references it:
<beans:bean id="crowdLogoutHandler" class="com.atlassian.crowd.integration.springsecurity.CrowdLogoutHandler"> <beans:property name="httpAuthenticator" ref="crowdHttpAuthenticator"/> </beans:bean> <beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> <beans:constructor-arg value="/index.jsp"/> <beans:constructor-arg> <beans:list> <beans:ref bean="crowdLogoutHandler"/> <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> </beans:list> </beans:constructor-arg> <beans:property name="filterProcessesUrl" value="/logout.jsp"/> </beans:bean>
Step 4. Restarting your Spring Security Application
Bounce your application. You should now have centralized authentication and single sign-on with Crowd.
Authorization
For the purposes of Crowd integration with Spring Security, you should map Spring Security's roles to Crowd's groups. To put it another way: in order to use Spring Security's authorization features, users in Crowd will have their Spring Security roles specified by their group names.
The authorities granted will use the authorityPrefix
specified on crowdUserDetailsService
. If no suffix is specified, the authorities will append the Crowd group name.
For example if user 'admin' is in the 'crowd-admin' group, then the user 'admin' will be authorized to view pages restricted to the 'ROLE_crowd-admin' role in Spring Security.
<http>
...
<intercept-url pattern="/console/secure/**" access="ROLE_crowd-administrators"/>
<intercept-url pattern="/console/info/**" access="ROLE_crowd-users"/>
<intercept-url pattern="/console/user/**" access="IS_AUTHENTICATED_FULLY"/>
...
</http>
If authoritySuffix
is also specified, any user in the mapped groups configured in crowd will be granted "authorityPrefix
+ authoritySuffix
" (for example, ROLE_ADMIN).
<beans:bean id="crowdUserDetailsService" ...>
...
<beans:property name="authorityPrefix" value="ROLE_"/>
<beans:property name="authorityPrefix" value="ADMIN"/>
</beans:bean>
<http>
...
<intercept-url pattern="/console/secure/**" access="ROLE_ADMIN"/>
<intercept-url pattern="/console/user/**" access="IS_AUTHENTICATED_FULLY"/>
...
</http>
RELATED TOPICS
- Integrating AppFuse - a Crowd-Spring Security Integration Tutorial
- Integrating Crowd with Acegi Security
- Using the Application Browser
- Adding an Application
- Configuring the Google Apps Connector
- Mapping a Directory to an Application
- Effective memberships with multiple directories
- Specifying an Application's Address or Hostname
- Testing a User's Login to an Application
- Enforcing Lower-Case Usernames and Groups for an Application
- Managing an Application's Session
- Deleting or Deactivating an Application
- Configuring Options for an Application
- Allowing applications to create user tokens
- Configuring how users log in