Spring Security极简入门三部曲(中篇)

大家好,我是白泽。通过上篇的学习,我们实现了一个简单的基于角色验证的小demo,但是不足之处在于用户和角色的信息我们写死在了内存中,而实际项目中必然是写在数据库里的,但是在将数据存入数据库之前,为了让你更深入理解Spring Security授权的验证流程,我需要为你介绍一些关键的接口和类(很遗憾这一部分无法完全避免),如果你只想继续学习Spring Security的使用,直接跳到demo时刻部分吧!

验证流程

Authentication接口

用户在前端输入的登陆信息传入后台后将封装入一个Authentication接口的实现类,它作为认证和授权的对象穿过整个过滤器链,反过来我们也能从Authentication实现类中取出用户账户的相关信息(用户名、密码、获取的权限等) Authentication实现类的获取方法:SecurityContextHolder.getContext().getAuthentication()

public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();//返回一组已经分发的权限(角色) Object getCredentials(); //返回凭证,即密码 Object getDetails(); Object getPrincipal(); //返回身份信息,即用户名 boolean isAuthenticated(); void setAuthenticated(boolean var1) throws IllegalArgumentException;
}

过滤器链

Spring Security框架核心有一个ProviderManager类,点开它的源码,它有一个List providers属性,这个List集合中就是存放着一个个AuthenticationProvider的实现类(定义了一个个权限验证的规则),这个List集合就组成了过滤器链

AuthenticationProvider接口:

public interface AuthenticationProvider {
Authentication authenticate(Authentication var1) throws AuthenticationException; boolean supports(Class<?> var1);
}

上面提到,ProviderManager实例的providers属性存放了AuthenticationProvider接口的实现类集合,而AuthenticationProvider实现类就是实现权限验证流程的关键,它主要需要实现AuthenticationProvider接口的authenticate()方法,这个方法接收一个Authentication实例,返回一个Authentication实例

结合上面那张ProviderManager的图,你是不是就理解过滤器链是如何工作的了?(一开始就提到了用户登陆之后,将数据封装为一个Authentication实例,并由这个实例通过整个过滤器链进行验证,而此时AuthenticationProvider接口的实现类的authenticate()方法不就实现了接收一个Authentication实例,返回一个Authentication实例吗?一个个AuthenticationProvider实现类组合在一起就得到了链式的验证流程

demo时刻

需要实现的功能:

  1. demo2保留demo1的所有功能,github项目地址

  2. 自定义一个验证器加入过滤器链(实现:当用户使用baize账户登陆时,无论密码是什么,都将获取USER和ADMIN权限)

代码讲解

事实上我们只新建了AuthenticationProvider接口的实现类BaiZeAuthenticationProvider,去重写它的两个方法,自定义了一个验证器。并在SecurityConfiguration类中完成注入(相当于自定义过滤器加入过滤器链)

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//从authentication实例中获取用户名和密码(这个authentication实例贯穿流程始终)
String username = authentication.getName();
String password = authentication.getCredentials().toString();
if (username.equals("baize")) {
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); //ROLE_ADMIN写法是固定的
authorities.add(new SimpleGrantedAuthority("ROLE_USER")); //ROLE_USER写法是固定的
return new UsernamePasswordAuthenticationToken(username, password, authorities);
} else {
return null;
}
}

小结

  1. 很抱歉我依旧没有为你讲解如何将用户、角色等数据存入数据库中,本节更多是介绍了Spring Security的验证流程,但相信你如果真的结合demo2学了下来,你的收获一定不小
  2. 我们自定义了一个验证器并将其加入过滤器链使黑客baize账户获取两个权限并完成登陆
  3. 白泽将在下一篇真正开始将数据存入数据库并构成第三个demo,敬请期待吧~
  4. 欢迎评论区留言

最新文章

  1. Node.js高效按行输出文件内容
  2. 出现异常:Unsupported major.minor version
  3. 请不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间【转】
  4. eclipse对Java程序的移植
  5. ie兼容整理
  6. abiword Related Pages
  7. centos6安装vncserver实现图形化访问
  8. 网络模块(net, http)小解
  9. jQuery之call()方法的使用
  10. BeanUtil拷贝
  11. 使用C#实现实体类和XML相互转换
  12. c 取读地图输入
  13. python模块——re模块(简单的计算器功能实现_eval版)
  14. 20155238 2016-2017-2 《Java程序设计》第二周学习总结
  15. CleanMyMac 4破解版-最强中文版_破解版_激活码_注册码
  16. Rotor envoy control plane 简单试用
  17. BASE64Decoder BASE64Encoder jar包问题
  18. 微信小程序从入坑到放弃之坑十二:navigator无法跳转的坑
  19. foreach使用和函数
  20. git上面创建个人简历-链接

热门文章

  1. Python切换版本工具pyenv
  2. [源码分析] 消息队列 Kombu 之 启动过程
  3. java实现回溯算法
  4. Dotnet洋葱架构实践
  5. 想了解FlinkX-Oracle Logminer?那就不要错过这篇文章
  6. c++ 反汇编 if
  7. 6、Spring教程之自动装配
  8. HarmonyOS三方件开发指南(14)-Glide组件功能介绍
  9. vps-java环境配置
  10. PHP并发抢购解决方案