The Price of all “Rest with Spring” course packages will increase by $50 next Friday:

>>> GET ACCESS NOW

1. Overview

This tutorial will show how to set up an Authentication Provider in Spring Security to allow for additional flexibility compared to the standard scenario using a simple UserDetailsService.

2. The Authentication Provider

Spring Security provides a variety of options for performing authentication – all following a simple contract – an Authentication request is processed by an AuthenticationProvider and a fully authenticated object with full credentials is returned.

The standard and most common implementation is the DaoAuthenticationProvider – which retrieves the user details from a simple, read-only user DAO – the UserDetailsService. This User Details Service only has access to the username in order to retrieve the full user entity – and in a large number of scenarios, this is enough.

More custom scenarios will still need to access the full Authentication request to be able to perform the authentication process – for example when authenticating against some external, third party service (such as Crowd) – both the username and the password from the authentication request will be necessary.

For these, more advanced scenarios, we’ll need to define a custom Authentication Provider:

@Component
public class CustomAuthenticationProvider
  implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException {
 
        String name = authentication.getName();
        String password = authentication.getCredentials().toString();
        
        if (shouldAuthenticateAgainstThirdPartySystem()) {
 
            // use the credentials
            // and authenticate against the third-party system
            return new UsernamePasswordAuthenticationToken(
              name, password, new ArrayList<>());
        } else {
            return null;
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(
          UsernamePasswordAuthenticationToken.class);
    }
}

Notice that the granted authorities set on the returned Authentication object are empty – this is because authorities are of course application specific.

3. Register the Auth Provider

Now that the Authentication Provider is defined, we need to specify it in the XML Security Configuration, using the available namespace support:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans 
  xmlns="http://www.springframework.org/schema/security" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:beans="http://www.springframework.org/schema/beans"
  xsi:schemaLocation="
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-4.0.xsd
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">

    <http use-expressions="true">
        <intercept-url pattern="/**" access="isAuthenticated()"/>
        <http-basic/>
    </http>

    <authentication-manager>
        <authentication-provider
          ref="customAuthenticationProvider" />
    </authentication-manager>

</beans:beans>

4. Java Configuration

Next, let’s take a look at the corresponding Java configuration:

@Configuration
@EnableWebSecurity
@ComponentScan("org.baeldung.security")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Autowired
    private CustomAuthenticationProvider authProvider;

    @Override
    protected void configure(
      AuthenticationManagerBuilder auth) throws Exception {
 
        auth.authenticationProvider(authProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
            .and()
            .httpBasic();
    }
}

5. Do Authentication

Requesting Authentication from the Client is basically the same with or without this custom authentication provider on the back end – we can use a simple curl command to send an authenticated request:

curl --header "Accept:application/json" -i --user user1:user1Pass 
    http://localhost:8080/spring-security-custom/api/foo/1

Note that – for the purposes of this example – we have secured the REST API with Basic Authentication.

And we get back the expected 200 OK from the Server:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=B8F0EFA81B78DE968088EBB9AFD85A60; Path=/spring-security-custom/; HttpOnly
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 02 Jun 2013 17:50:40 GMT

6. Conclusion

In this article, we discussed an example of custom authentication provider for Spring Security.

The full implementation of this tutorial can be found in the GitHub project – this is an Maven-based project, so it should be easy to import and run as it is.

The Price of all “Rest with Spring” course packages will increase by $50 next Friday:

>>> GET ACCESS NOW

Sort by:   newest | oldest | most voted
Stephane
Guest

Nice article. I had to explicitly instantiate the CustomAuthenticationProvider bean though.

Eugen Paraschiv
Guest

Yeah, if you don’t have claspath scanning enabled for that package – you’ll have to manually instantiate the bean. I find it easier to have scanning enabled.
Thanks. Eugen.

webiyo
Guest

Inside CustomAuthenticationProvider’s authenticate() method,

// returning null authentication
else {
return null;
}

is this a good idea ? what is the alternative ?? !!!

Eugen Paraschiv
Guest

Good catch – it’s better to throw AuthenticationException instead of simply returning null – I updated the example. Thanks.

webiyo
Guest
I am working on a project which should build two artifacts, 1) Spring MVC based UI [WEB-Project] secured by typical spring security 2) RestEasy based API layer [API-Project] secured by X-Auth-Token header. and one common java project for sharing RestEasy service interface definitions both in WEB & API projects. All the data access happens in API-Project, and API is using stateless spring security configuration with LDAP authentication WEB-Project is also using Spring Security but the authentication happens at API-Project layer and API-Project is responsible to provide authorization details to WEB-Project, authorization happens at both the layers ( duplicated ) !!!… Read more »
Eugen Paraschiv
Guest
That’s an interesting scenario – it sounds like it’s functional and the MVC project does authenticate (as well as retrieve the required artifacts for authorization) agains the API. This pattern looks similar to an older article here on baeldung. I have implemented something similar with a standard MVC application with standard login and Spring Security, and an API application secured separately (also with Spring Security). I choose to have the client (js) send requests to the API directly, and only use the MVC web project to serve out the HTML. The API part is on github (https://github.com/eugenp/REST) and I will… Read more »
Norman
Guest

Thanks for the tutorial. I have a question. You’ve provided the security configuration xml where authentication-provider ref=”customAuthenticationProvider” is set. Could you please point where and how bean with id=customAuthenticationProvider should be specified. Thanks in advance

Norman
Guest

Figured it out. Oh I’m such a noob. That bean can be defined in the XML Security Configuration as:

Burak
Guest

Can you give login.xhtml code ?

Eugen Paraschiv
Guest

I wrote in detail about login here
Hope it helps.
Cheers,
Eugen.

Burak
Guest

So customauthenticationprovider uses the login.xhtml on the link you give
Thanks

Eugen Paraschiv
Guest

One quick note about using comments – if you need to post any large code samples – please feel free to raise an issue on github and I’ll take a look (code doesn’t render well in comments).
Thanks. Eugen.

wpDiscuz