据我所知,当你想在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;
}
看起来两者都可以产生类似的结果。所以问题是有什么区别?何时使用一对另一对?
答案 0 :(得分:27)
答案在你的问题里面。 当您使用其他身份验证系统,并且您自己的数据库/数据模型中未提供密码时,您必须使用AuthenticationProvider。例如,我参与了一个客户拥有集中认证系统(CAS)的项目,因此我的系统不知道密码,我必须实现AuthenticationProvider并将给定的密码发送给CAS,并按照答案。
但是在另一个系统中,我将密码存储在我的数据库中,所以我所要做的就是实现UserDetailsService并检查用户是否存在于我的数据库中,spring-security必须完成剩下的工作。
答案 1 :(得分:6)
UserDetailsService经常存在一些混淆。它纯粹是用户数据的DAO,除了将数据提供给框架内的其他组件之外,不执行任何其他功能。特别是,它不会对用户进行身份验证,这是由AuthenticationManager完成的。在许多情况下,如果您需要自定义身份验证过程,则直接实现AuthenticationProvider会更有意义。
AuthenticationProvider和UserDetailsService有不同的用途。
AuthenticationProvider验证(比较)用户(请求)提供的用户名和密码与系统用户(这可以是任何系统,如DB维护注册用户列表)
UserDetailsService Implementation的责任是获取与用户提供的用户名匹配的系统用户详细信息。在这里,它只是获得具有相同用户名的用户,并且不告诉应用程序认证是成功还是失败。
示例: Spring提供以下作为默认设置来验证数据库
的用户详细信息看看这里更好地理解它:
AuthenticationProvider - DaoAuthenticationProvider 延伸AbstractUserDetailsAuthenticationProvider
UserDetailsService - JdbcDaoImpl
UserDetails - User
答案 2 :(得分:2)
这两者是相关的,但是被Spring Security故意分开。如果企业有多个系统,UserDetailsService将提供由您的特定系统保存的特定用户的信息,即使认证可能由另一个系统执行。在一个简单的系统中,它们可以组合在一起。例如,数据库调用将验证用户名/密码并检索该用户的所有电子邮件,ID等。
根据Spring Security Reference: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#getting-started
UserDetailsService经常存在一些混淆。它纯粹是用户数据的DAO,除了将数据提供给框架内的其他组件之外,不执行任何其他功能。特别是,它不会对用户进行身份验证,这是由AuthenticationManager完成的。在许多情况下,如果您需要自定义身份验证过程,则直接实现AuthenticationProvider会更有意义。