Client API Changes
Crowd 1.3 brings a rework of the internals of the Crowd Client library — see CWD-622. This page gives a summary of the API changes.
Description of the changes
- The static implementations of HttpAuthenticator and SecurityServerClient have been removed. They have been replaced with instantiable objects.
- The GenericClient has been removed and its functions have been absorbed into the new SecurityServerClient and the ClientProperties objects.
- The relationships in the new class structure are represented below:
Why go to non-static?
- Makes it easier to unit test your applications. Simply mock out the SecurityServerClient or HttpAuthenticator interfaces to test business logic without being tied to the collaborators.
- Allows you to have multiple 'applications' in one classloader.
But I liked my static calls!
- SecurityServerClientFactory and HttpAuthenticatorFactory are provided to allow for a fast migration to the new API. The logical functionality of the client and authenticator are unchanged.
- So for example, instead of:
HttpAuthenticator.isAuthenticated(request);
HttpAuthenticatorFactory.getHttpAuthenticator().isAuthenticated(request);
What are my options?
- Use the supplied factory methods to manage singleton instances, OR
- Externally manage singleton instances, e.g. via an IoC container like Spring.
Using the factories
The factories, HttpAuthenticatorFactory
and SecurityServerClientFactory
, provide quick access to implementations of the HttpAuthenticator
and SecurityServerClient
. They manage singleton instances of the beans. This means that if you do opt to use the factories, then you should never instantiate HttpAuthenticatorImpl
or SecurityServerClientImpl
directly.
The factories naturally assume that there is one application client per classloader, i.e. one SecurityServerClient
and one HttpAuthenticator
.
Using an IoC container
Managing the singleton implementations externally may be a convenient approach for applications that use an IoC container. For example, Spring could be used to manage the instances of SecurityServerClientImpl
and HttpAuthenticatorImpl
. In Crowd, internally, we use this approach.
If you would like to use the standard Spring configuration, which loads the client properties from crowd.properties
, simply add the applicationContext-CrowdClient.xml
from the classpath to your Spring configuration:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/applicationContext-CrowdClient.xml
</param-value>
</context-param>
This file is located in the crowd-integration-client.jar
.
If you would like to customize your own configuration, modify the bean configuration to suit your needs:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="propertyUtils" class="com.atlassian.crowd.util.PropertyUtils"/>
<bean id="clientProperties" class="com.atlassian.crowd.integration.service.soap.client.ClientProperties">
<constructor-arg ref="propertyUtils"/>
</bean>
<bean id="securityServerClient" class="com.atlassian.crowd.integration.service.soap.client.SecurityServerClientImpl">
<constructor-arg ref="clientProperties"/>
</bean>
<bean id="httpAuthenticator" class="com.atlassian.crowd.integration.http.HttpAuthenticatorImpl">
<constructor-arg ref="securityServerClient"/>
</bean>
<bean id="verifyTokenFilter" class="com.atlassian.crowd.integration.http.VerifyTokenFilter">
<constructor-arg ref="httpAuthenticator"/>
</bean>
<bean id="crowdAuthenticationInterceptor" class="com.atlassian.crowd.integration.xwork.CrowdAuthenticationInterceptor">
<constructor-arg ref="httpAuthenticator"/>
</bean>
</beans>
Make sure that you do not use the factories (either directly or implicitly) when externally managing singletons.
If you would like to use the VerifyTokenFilter
, you can use Spring to autowire the servlet filter by defining it in your web.xml
:
<filter>
<filter-name>verifyTokenFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>verifyTokenFilter</filter-name>
<url-pattern>/secure/*</url-pattern>
</filter-mapping>
This will protect all resources matching the /secure/*
pattern.