Java multi protocols (CAS, OAuth, OpenID, SAML, HTTP...) client for Spring Security (based on pac4j)
Java
Pull request Compare This branch is 159 commits behind pac4j:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src/main/java/org/pac4j/springframework/security
travis
.gitignore
.travis.yml
LICENSE
README.md
pom.xml

README.md

What is the spring-security-pac4j library ? Build Status

The spring-security-pac4j library is a web multi-protocols client for Spring Security.

It supports these 6 authentication mechanisms on client side :

  1. OAuth (1.0 & 2.0)
  2. CAS (1.0, 2.0, SAML, logout & proxy)
  3. HTTP (form & basic auth authentications)
  4. OpenID
  5. SAML (2.0)
  6. Google App Engine UserService.

It's available under the Apache 2 license and based on my pac4j library.

Providers supported

ProviderProtocolMaven dependencyClient classProfile class
CAS serverCASpac4j-casCasClient & CasProxyReceptorCasProfile
CAS server using OAuth WrapperOAuth 2.0pac4j-oauthCasOAuthWrapperClientCasOAuthWrapperProfile
DropBoxOAuth 1.0pac4j-oauthDropBoxClientDropBoxProfile
FacebookOAuth 2.0pac4j-oauthFacebookClientFacebookProfile
GitHubOAuth 2.0pac4j-oauthGitHubClientGitHubProfile
GoogleOAuth 2.0pac4j-oauthGoogle2ClientGoogle2Profile
LinkedInOAuth 1.0 & 2.0pac4j-oauthLinkedInClient & LinkedIn2ClientLinkedInProfile & LinkedIn2Profile
TwitterOAuth 1.0pac4j-oauthTwitterClientTwitterProfile
Windows LiveOAuth 2.0pac4j-oauthWindowsLiveClientWindowsLiveProfile
WordPressOAuth 2.0pac4j-oauthWordPressClientWordPressProfile
YahooOAuth 1.0pac4j-oauthYahooClientYahooProfile
PayPalOAuth 2.0pac4j-oauthPayPalClientPayPalProfile
VkOAuth 2.0pac4j-oauthVkClientVkProfile
FoursquareOAuth 2.0pac4j-oauthFoursquareClientFoursquareProfile
BitbucketOAuth 1.0pac4j-oauthBitbucketClientBitbucketProfile
ORCiDOAuth 2.0pac4j-oauthOrcidClientOrcidProfile
Web sites with basic auth authenticationHTTPpac4j-httpBasicAuthClientHttpProfile
Web sites with form authenticationHTTPpac4j-httpFormClientHttpProfile
Google - DeprecatedOpenIDpac4j-openidGoogleOpenIdClientGoogleOpenIdProfile
YahooOpenIDpac4j-openidYahooOpenIdClientYahooOpenIdProfile
SAML Identity ProviderSAML 2.0pac4j-samlSaml2ClientSaml2Profile
Google App Engine User ServiceGae User Service Mechanismpac4j-gaeGaeUserServiceClientGaeUserServiceProfile

Technical description

This library has only 4 classes :

  1. the ClientAuthenticationFilter class is called after authentication at the provider (on the /j_spring_pac4j_security_check url by default) : it creates the ClientAuthenticationToken token and calls the authentication manager to finish the authentication
  2. the ClientAuthenticationToken class is the token for an authentication (= provider's credentials + the user profile)
  3. the ClientAuthenticationProvider class is the provider responsible for authenticating ClientAuthenticationToken tokens : it calls the provider to get the access token and the user profile and computes the authorities
  4. the ClientAuthenticationEntryPoint class redirects the user to the provider for authentication.

and is based on the pac4j-* libraries.

Learn more by browsing the spring-security-pac4j Javadoc and the pac4j Javadoc.

How to use it ?

Add the required dependencies

If you want to use a specific client support, you need to add the appropriate Maven dependency in the pom.xml file :

  • for OAuth support, the pac4j-oauth dependency is required
  • for CAS support, the pac4j-cas dependency is required
  • for HTTP support, the pac4j-http dependency is required
  • for OpenID support, the pac4j-openid dependency is required
  • for SAML support, the pac4j-saml dependency is required
  • for Google App Engine, the pac4j-gae dependency is required.

For example, to add OAuth support, add the following XML snippet :

<dependency>
  <groupId>org.pac4j</groupId>
  <artifactId>pac4j-oauth</artifactId>
  <version>1.6.0</version>
</dependency>

As these snapshot dependencies are only available in the Sonatype snapshots repository, the appropriate repository must be added in the pom.xml file also :

<repositories>
  <repository>
    <id>sonatype-nexus-snapshots</id>
    <name>Sonatype Nexus Snapshots</name>
    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    <releases>
      <enabled>false</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </repository>
</repositories>

Define the clients

All the clients used to communicate with various providers (Facebook, Twitter, a CAS server...) must be defined in your Spring security context file. For example :

<bean id="facebookClient" class="org.pac4j.oauth.client.FacebookClient">
    <property name="key" value="fbkey" />
    <property name="secret" value="fbsecret" />
</bean>
<bean id="twitterClient" class="org.pac4j.oauth.client.TwitterClient">
    <property name="key" value="twkey" />
    <property name="secret" value="twsecret" />
</bean>
<bean id="usernamePasswordAuthenticator" class="org.pac4j.http.credentials.SimpleTestUsernamePasswordAuthenticator" />
<bean id="formClient" class="org.pac4j.http.client.FormClient">
    <property name="loginUrl" value="http://localhost:8080/theForm.jsp" />
    <property name="usernamePasswordAuthenticator" ref="usernamePasswordAuthenticator" />
</bean>
<bean id="basicAuthClient" class="org.pac4j.http.client.BasicAuthClient">
    <property name="usernamePasswordAuthenticator" ref="usernamePasswordAuthenticator" />
</bean>
<bean id="casClient" class="org.pac4j.cas.client.CasClient">
    <property name="casLoginUrl" value="http://localhost:8888/cas/login" />
</bean>
<bean id="clients" class="org.pac4j.core.client.Clients">
    <property name="callbackUrl" value="http://localhost:8080/callback" />
    <property name="clients">
    	<list>
    		<ref bean="facebookClient" />
    		<ref bean="twitterClient" />
    		<ref bean="formClient" />
    		<ref bean="basicAuthClient" />
    		<ref bean="casClient" />
    	</list>
    </property>
</bean>

Define the appropriate filter and provider

To authenticate/get the profile of the users in your application after they have been successfully authenticated at the providers, you need to define a filter to receive callbacks (with credentials from the providers) and a provider to finish the authentication process :

<bean id="clientFilter" class="org.pac4j.springframework.security.web.ClientAuthenticationFilter">
	<constructor-arg value="/callback"/>
    <property name="clients" ref="clients" />
    <property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="clientProvider" class="org.pac4j.springframework.security.authentication.ClientAuthenticationProvider">
    <property name="clients" ref="clients" />
</bean>

Protect the urls

You can protect your urls and force the user to be authenticated by a client by using the defining the appropriate security configuration with entry points. For example :

<security:http pattern="/facebook/**" entry-point-ref="facebookEntryPoint">
    <security:custom-filter after="CAS_FILTER" ref="clientFilter" />
    <security:intercept-url pattern="/facebook/**" access="IS_AUTHENTICATED_FULLY" />
</security:http>
<security:http pattern="/twitter/**" entry-point-ref="twitterEntryPoint">
    <security:custom-filter after="CAS_FILTER" ref="clientFilter" />
    <security:intercept-url pattern="/twitter/**" access="IS_AUTHENTICATED_FULLY" />
</security:http>
...
<security:http pattern="/**" entry-point-ref="casEntryPoint">
    <security:custom-filter after="CAS_FILTER" ref="clientFilter" />
    <security:intercept-url pattern="/cas/**" access="IS_AUTHENTICATED_FULLY" />
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <security:logout />
</security:http>
<bean id="facebookEntryPoint" class="org.pac4j.springframework.security.web.ClientAuthenticationEntryPoint">
    <property name="client" ref="facebookClient" />
</bean>
<bean id="twitterEntryPoint" class="org.pac4j.springframework.security.web.ClientAuthenticationEntryPoint">
    <property name="client" ref="twitterClient" />
</bean>
...
<bean id="casEntryPoint" class="org.pac4j.springframework.security.web.ClientAuthenticationEntryPoint">
    <property name="client" ref="casClient" />
</bean>

Get redirection urls

You can also explicitely compute a redirection url to a provider for authentication by using the getRedirectionUrl method of the client. For example with Facebook :

<%
	WebContext context = new J2EContext(request, response); 
    FacebookClient fbClient = (FacebookClient) application.getAttribute("FacebookClient");
    String redirectionUrl = fbClient.getRedirectionUrl(context, false, false);
%>

Get the user profile

After successful authentication, you can get the authentication of the user using the well-known SecurityContextHolder class :

ClientAuthenticationToken token = (ClientAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
// user profile
UserProfile userProfile = token.getUserProfile();
CommonProfile commonProfile = (CommonProfile) userProfile;

The profile returned is a CommonProfile, from which you can retrieve the most common properties that all profiles share. But you can also cast the user profile to the appropriate profile according to the provider used for authentication. For example, after a Facebook authentication :

// facebook profile
FacebookProfile facebookProfile = (FacebookProfile) commonProfile;

Or for all the OAuth 1.0/2.0 profiles, to get the access token :

OAuth10Profile oauthProfile = (OAuth10Profile) commonProfile
String accessToken = oauthProfile.getAccessToken();
// or
String accessToken = facebookProfile.getAccessToken();

Java config sample

@Configuration
public class Pac4jConfiguration {

  @Value("${google.key}")
  private String key;

  @Value("${google.secret}")
  private String secret;

  @Value("${callbackUrl}")
  private String callbackUrl;

  @Bean(initMethod = "init")
  public Clients clients() {
    return new Clients(callbackUrl, googleClient());
  }

  @Bean
  public Google2Client googleClient() {
    return new Google2Client(key, secret);
  }
}

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Autowired
  private Clients clients;

  @Autowired
  private Google2Client googleClient;

  @Override
  protected void configure(final HttpSecurity http) throws Exception {
    final ClientAuthenticationFilter clientFilter = new ClientAuthenticationFilter("/callback");
    clientFilter.setClients(clients);
    clientFilter.setAuthenticationManager(authenticationManager());
    final ClientAuthenticationEntryPoint googleEntryPoint = new ClientAuthenticationEntryPoint();
    googleEntryPoint.setClient(googleClient);
    http.authorizeRequests().antMatchers("/google").hasRole("USER").and()
      .addFilterBefore(clientFilter, AnonymousAuthenticationFilter.class).exceptionHandling()
      .authenticationEntryPoint(googleEntryPoint).and();
  }

  @Override
  protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    final ClientAuthenticationProvider clientProvider = new ClientAuthenticationProvider();
    clientProvider.setClients(clients);
    auth.authenticationProvider(clientProvider);
  }
}

Demo

A demo with Facebook, Twitter, CAS, form authentication and basic auth authentication providers is available at spring-security-pac4j-demo.

Versions

The current version 1.2.5-SNAPSHOT is under development. It's available on the Sonatype snapshots repository as a Maven dependency :

The last released version is the 1.2.4 :

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>spring-security-pac4j</artifactId>
    <version>1.2.4</version>
</dependency>

See the release notes.

Contact

If you have any question, please use the following mailing lists :