Spring Security到底在哪里进行密码方式认证

一 Spring Security比较好的教程

http://www.spring4all.com/article/428

二 基于数据库的密码认证

http://www.spring4all.com/article/420

三 该项目github地址

https://github.com/cakin24/spring-security-demos

Spring Security到底在哪里进行密码方式认证_第1张图片

四 先演示项目,再讲解原理

1 按照 https://github.com/cakin24/spring-security-demos/tree/master/00%20-%20%E6%B3%A8%E5%86%8C%E7%99%BB%E5%BD%95%EF%BC%88%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%89的使用手册先将环境搭建起来

2 启动项目

3 注册用户

http://localhost:8080/register

用户名:admin

密码:admin

注册后数据库中的数据

Spring Security到底在哪里进行密码方式认证_第2张图片

4 用刚注册的用户去登录

Spring Security到底在哪里进行密码方式认证_第3张图片

登录可以成功。

五 原理解释

到底是在Spring Security哪一块进行的密码验证呢?

其实主要是两个用户数据获取和一个比较。

第一个用户数据获取:从浏览器输入的用户和密码,用户名和密码会传递到Spring Security内部。

第二个用户数据获取:根据用户名从数据库获得用户详情。

一个比较:将前面两个数据获取进行比较,匹配则通过验证,否则验证不通过。

两个用户数据获取:http://www.spring4all.com/article/420 这篇博客写的很清楚

下面看看是哪里进行的密码比较

1 /spring-security-core-5.1.4.RELEASE-sources.jar!/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java

public Authentication authenticate(Authentication authentication)   // 重点关注这个函数,不重要先略去
      throws AuthenticationException {

   ......
   try {
      preAuthenticationChecks.check(user);
      // 重点看这个地方,additionalAuthenticationChecks这个函数会被DaoAuthenticationProvider实现。所以我们要看看DaoAuthenticationProvider的additionalAuthenticationChecks函数实现
      additionalAuthenticationChecks(user,(UsernamePasswordAuthenticationToken) authentication);         
   }
   catch (AuthenticationException exception) {
      if (cacheWasUsed) {
         // There was a problem, so try again after checking
         // we're using latest data (i.e. not from the cache)
         cacheWasUsed = false;
         user = retrieveUser(username,
               (UsernamePasswordAuthenticationToken) authentication);
         preAuthenticationChecks.check(user);
         additionalAuthenticationChecks(user,
               (UsernamePasswordAuthenticationToken) authentication);
      }
      else {
         throw exception;
      }
   }


   postAuthenticationChecks.check(user);


  ......

   return createSuccessAuthentication(principalToReturn, authentication, user);
}

2 /spring-security-core-5.1.4.RELEASE-sources.jar!/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java

protected void additionalAuthenticationChecks(UserDetails userDetails,
      UsernamePasswordAuthenticationToken authentication)
      throws AuthenticationException {
   if (authentication.getCredentials() == null) {
      logger.debug("Authentication failed: no credentials provided");


      throw new BadCredentialsException(messages.getMessage(
            "AbstractUserDetailsAuthenticationProvider.badCredentials",
            "Bad credentials"));
   }


   String presentedPassword = authentication.getCredentials().toString();
   // 密码比较就在这个地方,前面这个是用户输入的密码,后面这个是数据库存的密码,一致则通过
   if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
      logger.debug("Authentication failed: password does not match stored value");


      throw new BadCredentialsException(messages.getMessage(
            "AbstractUserDetailsAuthenticationProvider.badCredentials",
            "Bad credentials"));
   }
}

通过这两步分析,应该很清楚了吧。

你可能感兴趣的:(Spring,Security)