【问题标题】:Spring Security Custom Authentication - AuthenticationProvider vs UserDetailsServiceSpring Security 自定义身份验证 - AuthenticationProvider 与 UserDetailsS​​ervice
【发布时间】:2015-10-16 07:46:20
【问题描述】:

据我所知,当您希望在 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;
    }

看起来两者都可以产生相似的结果。所以问题是有什么区别?何时使用一个与另一个?

【问题讨论】:

  • 感谢您提出这个问题。仅仅因为你问它,它就为我阐明了架构。
  • @AdamEdison-MusicEducator 很高兴它有帮助。

标签: java spring spring-mvc spring-security


【解决方案1】:

答案在您的问题中。 当您使用不同的身份验证系统,并且您自己的数据库/数据模型中未提供密码时,您必须使用 AuthenticationProvider。例如,我在一个项目中工作过,客户有一个集中式身份验证系统(CAS),所以我的系统不知道密码,我必须实现 AuthenticationProvider 并将给定的密码发送到 CAS,并按照到它的答案。

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

【讨论】:

  • 在我的项目中,我正在创建用于检查身份验证的微服务。那是使用 UserDetails 服务并且已经部署在 AWS 中。我正在创建另一个服务,它调用已经部署在 aws 中的身份验证服务,在这种情况下,我可以选择哪个服务?我可以选择 authenticationProvider 吗? .还有 authenticationProvider 和 authenticationManager 有什么区别?
  • @Jacob authenticationManager 将认证任务委托给其认证提供者列表,每个提供者执行自己的认证方法,并在此基础上返回认证或抛出异常
【解决方案2】:

这两者是相关的,但被 Spring Security 故意分开。如果企业有多个系统,UserDetailsS​​ervice 将提供您的特定系统持有的特定用户信息,即使身份验证可能完全由另一个系统执行。在一个简单的系统中,它们可以组合在一起。例如,数据库调用将验证用户名/密码并检索该用户的所有电子邮件、ID 等。

根据 Spring Security Reference : http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#getting-started

关于 UserDetailsS​​ervice 经常有一些混淆。它纯粹是用户数据的 DAO,除了将数据提供给框架内的其他组件外,不执行任何其他功能。特别是,它不对用户进行身份验证,这是由 AuthenticationManager 完成的。在许多情况下,如果您需要自定义身份验证过程,直接实现 AuthenticationProvider 会更有意义。

【讨论】:

    【解决方案3】:

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

    关于 UserDetailsS​​ervice 经常有一些混淆。它纯粹是用户数据的 DAO,除了将数据提供给框架内的其他组件外,不执行任何其他功能。特别是,它不对用户进行身份验证,这是由 AuthenticationManager 完成的。在许多情况下,如果您需要自定义身份验证过程,直接实现 AuthenticationProvider 会更有意义。

    AuthenticationProvider 和 UserDetailsS​​ervice 有不同的用途。

    AuthenticationProvider 验证(比较)用户(请求)提供的用户名和密码与系统用户(这可以是任何系统,如维护注册用户列表的 DB)

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

    示例: Spring 提供以下默认设置来针对数据库验证用户详细信息

    • AuthenticationProvider - DaoAuthenticationProvider 它扩展了 AbstractUserDetailsAuthenticationProvider 通过传递用户名、身份验证对象来调用身份验证方法
    • UserDetailsS​​ervice - JdbcDaoImpl
    • 身份验证流程
    1. DaoAuthenticationProvider 的职责是向数据库用户验证从请求中获得的用户名和密码。
    2. 为了获取相应的数据库用户,它要求 UserDetailsS​​ervice 实现 JdbcDaoImpl 从数据库中获取与请求用户名相同的 UserDetail 对象。这里 JdbcDaoImpl 只是从系统中获取 UserDetails 对象。它要么发回在 DB 中找到的用户,要么发送未找到用户的异常。
    3. 如果在 DB 中找到用户详细信息,DaoAuthenticationProvider 然后继续检查请求用户密码和 DB 找到的用户密码,否则身份验证失败。
    4. DaoAuthenticationProvider 将根据 JdbcDaoImpl 响应响应用户是否通过身份验证。

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

    AuthenticationProvider - DaoAuthenticationProvider 扩展AbstractUserDetailsAuthenticationProvider

    UserDetailsS​​ervice - JdbcDaoImpl

    用户详情 - User

    【讨论】:

      猜你喜欢
      • 2015-10-12
      • 2014-10-06
      • 2015-06-02
      • 2018-12-06
      • 2013-05-02
      • 2014-06-16
      • 2013-02-11
      • 2011-06-20
      • 2017-12-08
      相关资源
      最近更新 更多