spring-security-authentication-provider
Spring Security Authentication Provider
1. Overview
2. The Authentication Provider
Spring Security provides a variety of options for performing authentication. These follow 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. This is enough for most scenarios.
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 we’ve defined the Authentication Provider, we need to specify it in the XML Security Configuration, using the available namespace support:
<http use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()"/>
<http-basic/>
</http>
<authentication-manager>
<authentication-provider
ref="customAuthenticationProvider" />
</authentication-manager>
4. 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. Performing Authentication
Requesting Authentication from the Client is basically the same with or without this custom authentication provider on the back end.
Let’s 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
For the purposes of this example, we’ve 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
The full implementation of this tutorial can be found in the GitHub project.