Spring Безопасность Пользовательская аутентификация - AuthenticationProvider vs UserDetailsService
Насколько я могу понять, когда вы хотите выполнить специальную проверку подлинности в Spring Security, вы можете либо реализовать пользовательский AuthenticationProvider
или пользовательский UserDetailsService
.
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
//.authenticationProvider(authProvider) // option 1
.userDetailsService(userDetailsService); // option 2
}
В AuthenticationProvider вы можете проверить имя пользователя и пароль и вернуть Authentication
своим пользовательским объектом.
public Authentication authenticate(Authentication authentication){
if (checkUsernameAndPassword(authentication)) {
CustomUserDetails userDetails = new CustomUserDetails();
//add whatever you want to the custom user details object
return new UsernamePasswordAuthenticationToken(userDetails, password, grantedAuths);
} else {
throw new BadCredentialsException("Unable to auth against third party systems");
}
}
В UserDetailsService
вы получаете только имя пользователя и когда вы возвращаете пользовательские UserDeatails, фреймворк выполняет проверку пароля.
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
CustomUserDetails user = new CustomUserDetails();
//add whatever you want to the custom user details object
return user;
}
Похоже, что обе могут давать похожие результаты. Итак, вопрос в чем разница? Когда пользователь один против другого?
Ответы
Ответ 1
Ответ внутри вашего вопроса.
когда вы используете другую систему аутентификации, а пароль не указан в вашей собственной базе данных/модели данных, вы должны использовать AuthenticationProvider. например, я работал в проекте, что у клиента была централизованная система аутентификации (CAS), поэтому моя система не знала о пароле, мне пришлось реализовать AuthenticationProvider и отправить данный пароль в CAS и действовать согласно к его ответу.
Но в другой системе я сохранял пароль в своей базе данных, поэтому все, что мне нужно было сделать, это реализовать UserDetailsService и проверить, существует ли пользователь в моей базе данных или нет, spring -security должен был сделать все остальное.
Ответ 2
Эти два связаны друг с другом, но намеренно разделяются Spring Security. Если у предприятия есть несколько систем, UserDetailsService предоставит конкретную информацию пользователя, хранящуюся в вашей конкретной системе, даже если аутентификация МОЖЕТ быть выполнена совершенно другой системой. В простой системе их можно комбинировать. Например, вызов базы данных проверяет имя пользователя/пароль и извлекает все эти электронные письма, идентификатор и т.д.
Согласно Spring Справочник по безопасности:
http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#getting-started
Часто возникает проблема с UserDetailsService. Это чисто DAO для пользовательских данных и не выполняет никакой другой функции, кроме предоставления этих данных другим компонентам в рамках. В частности, он не аутентифицирует пользователя, который выполняется AuthenticationManager. Во многих случаях имеет смысл внедрить AuthenticationProvider напрямую, если вам нужен пользовательский процесс проверки подлинности.
Ответ 3
Из spring документации безопасности,
https://docs.spring.io/spring-security/site/docs/5.0.0.RC1/reference/htmlsingle/#overall-architecture
Часто возникает проблема с UserDetailsService. Это чисто DAO для пользовательских данных и не выполняет никакой другой функции, кроме предоставления этих данных другим компонентам в рамках. В частности, он не аутентифицирует пользователя, который выполняется AuthenticationManager. Во многих случаях имеет смысл внедрить AuthenticationProvider напрямую, если вам нужен пользовательский процесс проверки подлинности.
AuthenticationProvider и UserDetailsService имеют другую цель.
АутентификацияProvider аутентифицирует (сравнивает) пользователя (запроса), предоставленного пользователю и паролю для пользователя системы (это может быть любая система, такая как БД, которая ведет список зарегистрированных пользователей)
Ответственность за выполнение UserDetailsService Реализация позволяет получить информацию о пользователе системы, которая соответствует пользователю, указанному пользователем. Здесь он просто получает пользователей, имеющих одинаковое имя пользователя, и не сообщает приложению, является ли проверка подлинности успешной или неудачной.
Пример:
Spring предоставляет следующую настройку для аутентификации данных пользователя в базе данных по умолчанию
- АутентификацияProvider - DaoAuthenticationProvider
который расширяет AbstractUserDetailsAuthenticationProvider, который вызывает метод аутентификации, передавая имя пользователя, объект аутентификации
- UserDetailsService - JdbcDaoImpl
- Поток аутентификации
- Ответственность DaoAuthenticationProvider заключается в том, чтобы аутентифицировать имя пользователя и пароль, полученные из запроса, с помощью пользователя базы данных.
- Чтобы получить соответствующего пользователя базы данных, он запрашивает UserDetailsService Implementataion JdbcDaoImpl, чтобы получить объект UserDetail из базы данных с именем, аналогичным запросу username.Here JdbcDaoImpl просто извлекает объект UserDetails из системы. Он либо отправит обратно пользователя, найденного в БД, либо отправить исключение, что пользователь не найден.
- Если данные пользователя находятся в БД, DaoAuthenticationProvider затем проверяет пароль пользователя с запросом пароля, а пароль администратора еще не завершает проверку подлинности.
- DaoAuthenticationProvider ответит, аутентифицирован ли пользователь или нет на основе ответа JdbcDaoImpl.
Посмотрите здесь, чтобы лучше понять:
AuthenticationProvider - DaoAuthenticationProviderextends AbstractUserDetailsAuthenticationProvider
UserDetailsService - JdbcDaoImpl
UserDetails - User