I am trying to add login functionality with a database lookup with Spring Security, and I am really struggling. I want to look up the user by implementing the UserDetailsService
interface. I have read a ton of documentation and Googled for hours, but I am still stuck. Most of the examples that I could find are using XML, so maybe my problems are related to converting those to Java configuration.
UserDetailsService
@Service
public class AccountServiceImpl implements AccountService { // AccountService implements UserDetailsService
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
// The email variable is always ''
List<GrantedAuthority> authList = new ArrayList<>();
authList.add(new Role("ROLE_USER")); // Role implements GrantedAuthority
return new User("test@example.com", "password", true, true, true, true, authList);
}
}
Security config
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private LogoutSuccessHandler logoutSuccessHandler;
@Autowired
private AccountService accountService;
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
// This bean is required for using method security annotations
return super.authenticationManager();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login/process")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/", false)
.and()
//.userDetailsService(this.accountService)
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(this.logoutSuccessHandler)
.invalidateHttpSession(true)
.and()
// Permissions here
.csrf().disable();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("test@example.com").password("password").roles("USER");
}
/*@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
//.userDetailsService(this.accountService);
.inMemoryAuthentication()
.withUser("test@example.com").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}*/
/*@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(this.accountService);
return provider;
}*/
}
As you can see, there is a bunch of outcommented code, which are just some of the things I tried to make it work. I also tried with simple in-memory authentication, but that didn't work either.
login.jsp
<form action="/login/process" method="POST">
<input name="j_username" id="j_username" type="text" />
<input name="j_password" id="j_password" type="password" />
<input type="submit" value="Login" />
</form>
Debug
DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Request is to process authentication
DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
DEBUG org.springframework.security.authentication.dao.DaoAuthenticationProvider - User '' not found
DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
The above seems to always be the case for all of the configurations that I tried. I am not even sure why the DaoAuthenticationProvider
is used, even if I try to override it; I guess it's a default. For some of the configuration above, my UserDetailsService
implementation gets called, but with an empty string as the parameter. Also, even if I return a hard coded UserDetails
object with the same credentials as the ones I entered in my form, the authentication still fails, and I get redirected back to /login?error=true
.
What am I doing wrong here? Please inform me about my mistakes or provide a simple example using Java configuration. Thanks!
When using Spring Security with Java based configuration the name of the request parameters are username
and password
and not j_username
and j_password
anymore.
You can either fix your login form
<form action="/login/process" method="POST">
<input name="username" id="j_username" type="text" />
<input name="password" id="j_password" type="password" />
<input type="submit" value="Login" />
</form>
or adapt your configuration to use the old field names.
formLogin().usernameParameter("j_username").passwordParameter("j_password");
Either way will resolve your issue.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.