Spring Security Custom Authentication - AuthenticationProvider vs UserDetailsService

2022-08-31 15:56:38

据我所知,当您想要在Spring Security中进行自定义身份验证时,您可以实现自定义或自定义 。AuthenticationProviderUserDetailsService

@Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth    
            //.authenticationProvider(authProvider)  // option 1
            .userDetailsService(userDetailsService); // option 2

    }

在身份验证提供程序中,您可以检查用户名和密码,并在其中返回自定义对象。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");
        }
    }

在 中,您只能获得用户名,当您返回自定义 UserDeatails 时,框架将对密码执行检查。UserDetailsService

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        CustomUserDetails user = new CustomUserDetails();
        //add whatever you want to the custom user details object
        return user;
    }

看起来两者都可以产生类似的结果。那么问题来了,它们之间有什么区别呢?何时使用一个与另一个?


答案 1

答案就在你的问题里面。当您使用不同的身份验证系统,并且您自己的数据库/数据模型中未提供密码时,您必须使用身份验证提供程序。例如,我曾在一个项目中工作,客户有一个集中式身份验证系统(CAS),所以我的系统不知道密码,我必须实现身份验证提供程序并将给定的密码发送到CAS,并根据其答案采取行动。

但是在另一个系统中,我将密码存储在我的数据库中,所以我所要做的就是实现UserDetailsService并检查用户是否存在于我的数据库中,spring-security必须完成其余的工作。


答案 2

从春季安全文档,https://docs.spring.io/spring-security/site/docs/5.0.0.RC1/reference/htmlsingle/#overall-architecture

关于用户详细信息服务经常存在一些混淆。它纯粹是用户数据的DAO,除了将该数据提供给框架内的其他组件之外,不执行任何其他功能。特别是,它不对用户进行身份验证,这是由身份验证管理器完成的。在许多情况下,如果需要自定义身份验证过程,则直接实现身份验证提供程序更有意义。

身份验证提供程序和用户详细信息服务具有不同的用途。

身份验证提供程序根据系统用户(请求)提供的用户名和密码进行身份验证(比较)用户(这可以是维护注册用户列表的任何系统,如DB)

用户详细信息服务实现负责获取与用户提供的用户名匹配的系统用户详细信息。在这里,它只是获取具有相同用户名的用户,而不会告诉应用程序身份验证是成功还是失败。

示例:Spring提供以下内容作为默认设置,以根据数据库验证用户详细信息

  • 身份验证提供程序 - DaoAuthenticationProvider,它扩展了 AbstractUserDetailsAuthentication 通过传递用户名、身份验证对象来调用身份验证方法的提供程序
  • UserDetailsService - JdbcDaoImpl
  • 身份验证流程
  1. DaoAuthenticationProvider 的责任是验证从数据库用户请求中获得的用户名和密码。
  2. 为了获取相应的数据库用户,它要求 UserDetailsService Implementataion JdbcDaoImpl 从数据库中获取一个名称与请求用户名相同的 UserDetail 对象。在这里,JdbcDaoImpl只是从系统中获取UserDetails对象。它将发回在 DB 中找到的用户,或者发送未找到用户的异常。
  3. 如果在DB中找到用户详细信息,则DaoAuthenticationProvider继续检查请求用户密码,DB找到用户密码,否则身份验证失败。
  4. DaoAuthenticationProvider 将根据 JdbcDaoImpl 响应来响应用户是否经过身份验证。

看看这里,以更好地理解它:

AuthenticationProvider - DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider

UserDetailsService - JdbcDaoImpl

用户详细信息 - 用户


推荐