Reputation: 1178
I'm working on a simple Spring Boot app using Spring Security. And I hardcoded an username and password, but the problem is that I can login with any username, only the password is checked by Spring Security.
This is the code:
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
public final MyUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
MyUserDetailsService class:
@Service
public class MyUserDetailsService implements UserDetailsService {
private static final String USERNAME = "john";
private static final String PASSWORD = "$2a$10$5yPLXyd0J2TEHhsbD3Azjumpn6OePKsiV1XPpFaZfytT33mRAn3N6";
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return new org.springframework.security.core.userdetails
.User(USERNAME, PASSWORD, new ArrayList<>());
}
}
Rest Controller class:
@RestController
public class ApiController {
@GetMapping("/hello")
public String sendMoney() {
return "Hello World!";
}
}
I hardcoded the username "john" and password "test" encrypted with BCrypt. But the problem is that I can login with any username, only the password should be "test". Can somebody explain me why? Why Spring Security is checking only the password to be "test", but it doesn't check for the username to be "john"? Any feedback will be apreciated. Thank you!
Upvotes: 1
Views: 769
Reputation: 24251
You seem to ignore the argument s
to:
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
so in other words - for whatever user details the code is asked to retrieve, it retrieves the hard-coded ones. User "notjohn"? Sure we have it. User "notexisting"? We also have it, etc.
I guess your intention is to have a check if s
equals to "john"
and only return the hard-coded user details if the requested username is "john"
.
Upvotes: 1
Reputation: 148890
This is by design. UserDetailsService.loadUserByUsername(String user)
is expected to provide the record corresponding to user
. It is acceptable to use a hardcoded record, but then you are responsable to control that the user name is correct.
But in fact, if you want SpringSecurity to test both the user name and the password, you should not implement a custom UserDetailService
, but directly use a InMemoryUserDetailsManager
that provides it out of the box.
Upvotes: 2