Implementing Custom Authentication Logic in Spring Security
When implementing custom authentication logic, Spring Security requires both UserDetailsService and PasswordEncoder components. A PasswordEncoder instance must be present in the application context, meaning direct instantiation is not permitted.
1. Configuration Class Setup
Create a security configuration class that defines the PasswordEncoder bean:
@Configuration
public class SecurityConfiguration {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
2. Custom Authentication Implementation
The UserDetailsService interface handles user authentication logic. Implement this service with your custom validation:
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if(!"admin".equals(username)) {
throw new UsernameNotFoundException("User not found");
}
String encodedPassword = passwordEncoder.encode("123");
return new User(username, encodedPassword,
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
After restarting the application, authentication with username 'admin' and password '123' will succeed.
Custom Login Page Implementation
Spring Security allows customization of the login page through configuration adjustments.
1. Login Page HTML
Create a custom login form with appropriate action and input fields:
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="/auth" method="post">
<input type="text" name="username"/>
<input type="password" name="password"/>
<input type="submit" value="Login"/>
</form>
</body>
</html>
2. Security Configuration Update
Extend WebSecurityConfigurerAdapter too configure custom login behavior:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginProcessingUrl("/auth")
.successForwardUrl("/dashboard")
.loginPage("/custom-login.html");
http.authorizeRequests()
.antMatchers("/custom-login.html").permitAll()
.anyRequest().authenticated();
http.csrf().disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
3. Controller Setup
Create a controller to handle successful authentication redirects:
@Controller
public class AuthController {
@PostMapping("/dashboard")
public String dashboard() {
return "redirect:/main.html";
}
}