📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
✅ Some premium posts are free to read — no account needed. Follow me on Medium to stay updated and support my writing.
🎓 Top 10 Udemy Courses (Huge Discount): Explore My Udemy Courses — Learn through real-time, project-based development.
▶️ Subscribe to My YouTube Channel (172K+ subscribers): Java Guides on YouTube
The Role of AuthenticationProvider
The AuthenticationProvider is an interface in Spring Security that encapsulates the authentication logic. It is responsible for verifying the authenticity of an authentication request and, if successful, returning a fully populated Authentication object.public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication);
boolean supports(Class<?> authentication);
}
Spring security provides a different implementation of AuthenticationProvider. For example, DaoAuthenticationProvider, LdapAuthenticationProvider, etc. We can also write our own custom authentication provider using the implementing AuthenticationProvider interface. Core Responsibilities
Supports Different Authentication Types: By implementing multiple AuthenticationProviders, Spring Security can support a wide range of authentication mechanisms.
Flexible and Extensible: Developers can create custom AuthenticationProviders to incorporate any authentication mechanism into their Spring Security configuration.
Implementing Custom AuthenticationProvider
Implementing an AuthenticationProvider involves overriding two key methods: authenticate and supports. The authenticate method contains the custom logic for validating user credentials, while the supports method indicates the type of Authentication objects that this provider can process.Example 1: Creating a Custom AuthenticationProvider (hardcoded credentials)
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
// Implement your authentication logic here
if ("admin".equals(username) && "password".equals(password)) {
return new UsernamePasswordAuthenticationToken(username, password, List.of(new SimpleGrantedAuthority("ROLE_ADMIN")));
} else {
throw new BadCredentialsException("Invalid username or password");
}
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
In this example, the authenticate method checks if the provided credentials match the hardcoded username and password. If successful, it returns an Authentication object with the ROLE_ADMIN authority.Example 2: Database Authentication
One more common use case is authenticating users against credentials stored in a database. This requires loading user details from the database and comparing them with the credentials provided during the login attempt.@Component
public class CustomDatabaseAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserService userService; // A service that loads user details from the database
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
UserDetails user = userService.loadUserByUsername(username);
if (user != null && password.equals(user.getPassword())) {
return new UsernamePasswordAuthenticationToken(username, password, user.getAuthorities());
} else {
throw new BadCredentialsException("Authentication failed for " + username);
}
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
Example 2: Configuring Spring Security to Use the Custom AuthenticationProvider
@Configuration
@EnableWebSecurity
@ComponentScan("com.baeldung.security")
public class SecurityConfig {
@Autowired
private CustomAuthenticationProvider authProvider;
@Bean
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder =
http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.authenticationProvider(authProvider);
return authenticationManagerBuilder.build();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(request -> request.anyRequest()
.authenticated())
.httpBasic(Customizer.withDefaults())
.build();
}
}
Example 4: External Service Authentication
public class ExternalServiceAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
// Logic to authenticate against an external service
if (externalService.authenticate(username, password)) {
return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList());
} else {
throw new BadCredentialsException("External authentication failed");
}
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
Comments
Post a Comment
Leave Comment