#java #spring-boot #authentication #spring-security
#java #spring-boot #аутентификация #spring-безопасность
Вопрос:
Я работаю над простым приложением Spring Boot с использованием Spring Security. И я жестко ввел имя пользователя и пароль, но проблема в том, что я могу войти в систему с любым именем пользователя, только пароль проверяется Spring Security.
Это код:
@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:
@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:
@RestController
public class ApiController {
@GetMapping("/hello")
public String sendMoney() {
return "Hello World!";
}
}
Я жестко запрограммировал имя пользователя «john» и пароль «test», зашифрованные с помощью BCrypt. Но проблема в том, что я могу войти в систему под любым именем пользователя, только пароль должен быть «тестовый». Может кто-нибудь объяснить мне, почему? Почему Spring Security проверяет только пароль на «тест», но не проверяет, является ли имя пользователя «john»? Любая обратная связь будет оценена. Спасибо!
Ответ №1:
Это сделано специально. UserDetailsService.loadUserByUsername(String user)
ожидается, что будет предоставлена запись, соответствующая user
. Допустимо использовать жестко закодированную запись, но тогда вы несете ответственность за правильность имени пользователя.
Но на самом деле, если вы хотите, чтобы SpringSecurity проверял как имя пользователя, так и пароль, вам не следует внедрять пользовательский UserDetailService
, а напрямую использовать a InMemoryUserDetailsManager
, который предоставляет его из коробки.
Ответ №2:
Кажется, вы игнорируете аргумент s
:
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
другими словами, для любых пользовательских данных, которые запрашивается у кода, он извлекает жестко запрограммированные. Пользователь «notjohn»? Конечно, у нас это есть. Пользователь «не существует»? У нас тоже есть и т. Д.
Я предполагаю, что ваше намерение состоит в том, чтобы проверить, s
равно ли "john"
и возвращает жестко заданные данные пользователя, только если запрошенное имя пользователя "john"
.