无需云厂商的动态DNS和负载均衡
|
该方法就是将常量 USER_NOT_FOUND_PASSWORD 使用 passwordEncoder 编码之后(如果不了解 passwordEncoder,可以参考 Spring Boot 中密码加密的两种姿势!一文),将编码结果赋值给 userNotFoundEncodedPassword 变量。 2.接下来调用 loadUserByUsername 方法,根据登录用户传入的用户名去数据库中查询用户,如果查到了,就将查到的对象返回。 3.如果查询过程中抛出 UsernameNotFoundException 异常,按理说直接抛出异常,接下来的密码比对也不用做了,因为根据用户名都没查到用户,这次登录肯定是失败的,没有必要进行密码比对操作! 但是大家注意,在抛出异常之前调用了 mitigateAgainstTimingAttack 方法。这个方法从名字上来看,有缓解计时攻击的意思。
我们来看下该方法的执行流程: 这段代码位于 DaoAuthenticationProvider 类中,为了方便大家理解,我来简单说下这段代码的上下文环境。 当用户提交用户名密码登录之后,Spring Security 需要根据用户提交的用户名去数据库中查询用户。 查到用户对象之后,再去比对从数据库中查到的用户密码和用户提交的密码之间的差异。 而上面这段代码就是 Spring Security 根据用户登录时传入的用户名去数据库中查询用户,并将查到的用户返回。方法中还有一个 authentication 参数,这个参数里边保存了用户登录时传入的用户名/密码信息。 那么这段代码有什么神奇之处呢? 我们来一行一行分析。 源码梳理
1.首先方法一进来调用了 prepareTimingAttackProtection 方法,从方法名字上可以看出,这个是为计时攻击的防御做准备,那么什么又是计时攻击呢?别急,松哥一会来解释。我们先来吧流程走完。prepareTimingAttackProtection 方法的执行很简单,如下: 像前文所说,这里线程启动的方式和刚才的稍有不同,因为新建的的这个类只是实现了 Runnable 接口,所以还需要一个线程来“代理”执行它,所以需要把我们新建的这个类的实例传入到一个线程里,这里其实是代理模式。这个设计模式之后再细讲。 小结 那这两种方式哪种好呢? 使用 Runnable 接口更好,主要原因是 Java 单继承。 另外需要注意的是,在启动线程的的时候用的是 start(),而不是 run()。 调用 run() 仅仅是调用了这个方法,是普通的方法调用;而 start() 才是启动线程,然后由 JVM 去调用该线程的 run() 。
好了,以上就是多线程第一篇的所有内容了,这里主要是帮助大家复习一下基础概念,以及没有接触过多线程的小伙伴可以入门。想看更多关于多线程的文章的话,记得给我点赞留言哦~ (编辑:平顶山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

