springsecurity3的验证过程

来源:互联网 发布:彩票网站源码迅驰彩票 编辑:程序博客网 时间:2024/04/29 17:00

最近做项目的时候用到了springsecurity,正如所有的spring工具一大堆xml配置文件,而且表单提交的url也是写好的j_spring_security_check,似乎所有的验证过程都封装好了让人不禁想探索它到底是如何实现验证的(这里要说明的是在配置中的ProviderManager类的List<AuthenticationProvider> providers属性也就是验证类型注入的是DaoAuthenticationProvider也就是最常用的数据库数据验证,其他的方式我没用过),显然springsecurity给我们留下了一个唯一的通道也就是userDetailsService这个类,我们需要做的就是自己写这个类的实现,这个类需要重写loadUserByUsername(String userName)方法,作用很明显就是通过username来查询数据库用户的信息,然后构建一个能被框架所使用的User对象,这个User对象包括账号,密码,是否被锁定,当然最重要的就是这个对象是否拥有登录的权限这个权限放在User对象中的Collection<GrantedAuthority> authorities这个集合中,在配置中我们可以配置页面需要什么样的权限比如拥有ROLE_ALERT才能登录,如果某个用户是可以被允许登录的,那我们就可以像这个集合中添加一个权限,比如authorities.add(new SimpleGrantedAuthority("ROLE_ALERT"))。

上面说的都是最基础的估计大家都比较熟悉,现在我们开始探索到底是如何将表单中的数据提交到后台跟数据库的密码做对比校验密码是否正确的呢?经过我的断点跟踪,我发现所有验证的入口就在org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter 类中的attemptAuthentication()方法我们来看一下这个方法。

可以看到这里有一个obtainUsername(request)和obtainPassword(request),大家可以看一下这两个方法,很容易看出,这两个方法就是我们想要找的获取表单输入的用户名和密码的信息,然后通过这两个重要信息构建一个类型为UsernamePasswordAuthenticationToken的对象,然后将这个对象传入到authenticate()方法,显然这个方法就是实现验证的逻辑所在。要想知道这个方法的逻辑,我们必须先知道这个方法是哪个对象所有,所以我们先看一下这个this.getAuthenticationManager()方法得到的是什么:

得到的是UsernamePasswordAuthenticationFilter的父类AbstractAuthenticationProcessingFilter中的AuthenticationManager类型的属性authenticationManager,而这个属性相信大家都很熟悉了,因为我们我们在配置文件中写的ProviderManager正是AuthenticationManager接口的一个实现,也就是说我们其实是 将 PrividerManager 注入 到了AbstractAuthenticationProcessingFilter类中,而ProviderManager中有一个List<AuthenticationProvider> providers的属性,我们通过spring配置将
org.springframework.security.authentication.dao.DaoAuthenticationProvider 注入到 这个List中,ProviderManager的authenticate方法中可以看到其实是循环调用list
中的每一个子类的authenticate()方法我们使用的DaoAuthenticationProvider类型的验证调用的就是其父类AbstractUserDetailsAuthenticationProvider中的authenticate()方法,


而这个方法中的构建User的方法retrieveUser()则是由DaoAuthenticationProvider自己实现的,调 很清楚的可以看到这里调用了我们自己写的UserDetails的实现UserDetailsImpl的loadUserByUsername(String username)方法 返回一个User对象
retrieveUser()调用之后再调用additionalAuthenticationChecks()传入构建的User对象以及表单提交构建的UsernamePasswordAuthenticationToken对象,
additionalAuthenticationChecks()这个方法也是由DaoAuthenticationProvider自己实现


可以看到这里完成了最终的比对逻辑实现了密码的匹配从而实现校验密码的功能。

0 0
原创粉丝点击