本文来说下SpringSecurity如何动态加载用户角色权限实现登录及鉴权

文章目录

  • 概述
  • 动态数据登录验证的基础知识
  • UserDetails与UserDetailsService接口
  • 实现UserDetails 接口
  • 实现UserDetailsService接口
  • 本文小结

概述

很多人觉得Spring Security实现登录验证很难,我最开始学习的时候也这样觉得。因为我好久都没看懂我该怎么样将自己写的用于接收用户名密码的Controller与Spring Security结合使用,这是一个先入为主的误区。后来我搞懂了:根本不用你自己去写Controller。你只需要告诉Spring Security用户信息、角色信息、权限信息、登录页是什么?登陆成功页是什么?或者其他有关登录的一切信息。具体的登录验证逻辑它来帮你实现。


动态数据登录验证的基础知识

在之前的文章中,已经介绍了Spring Security的formLogin登录认证模式,RBAC的权限控制管理模型,并且针对Spring Security的登录认证逻辑源码进行了解析等等。我们所有的用户、角色、权限信息都是在配置文件里面写死的,然而在实际的业务系统中,这些信息通常是存放在RBAC权限模型的数据库表中的。

下面我们来回顾一下其中的核心概念:

  • RBAC的权限模型可以从用户获取为用户分配的一个或多个角色,从用户的角色又可以获取该角色的多种权限。通过关联查询可以获取某个用户的角色信息和权限信息。
  • 在源码解析的文章中,我们知道如果我们不希望用户、角色、权限信息写死在配置里面。我们应该实现UserDetails与UserDetailsService接口,从而从数据库或者其他的存储上动态的加载这些信息。

以上是对一些核心的基础知识的总结,如果您对这些知识还不是很清晰,建议您先往下读本文。如果看完本文仍然理解困难,建议您翻看本号之前的文章。


UserDetails与UserDetailsService接口

UserDetails与UserDetailsService接口

  • UserDetailsService接口有一个方法叫做loadUserByUsername,我们实现动态加载用户、角色、权限信息就是通过实现该方法。函数见名知义:通过用户名加载用户。该方法的返回值就是UserDetails。
  • UserDetails就是用户信息,即:用户名、密码、该用户所具有的权限。

UserDetailsService接口

下面我们来看一下UserDetails接口都有哪些方法

 public interface UserDetails extends Serializable {//获取用户的权限集合Collection<? extends GrantedAuthority> getAuthorities();//获取密码String getPassword();//获取用户名String getUsername();//账号是否没过期boolean isAccountNonExpired();//账号是否没被锁定boolean isAccountNonLocked();//密码是否没过期boolean isCredentialsNonExpired();//账户是否可用boolean isEnabled();}

现在,我们明白了,只要我们把这些信息提供给Spring Security,Spring Security就知道怎么做登录验证了,根本不需要我们自己写Controller实现登录验证逻辑。


实现UserDetails 接口

实现UserDetails 接口

 public class SysUser implements UserDetails{String password;  //密码String username;  //用户名boolean accountNonExpired;   //是否没过期boolean accountNonLocked;   //是否没被锁定boolean credentialsNonExpired;  //是否没过期boolean enabled;  //账号是否可用Collection<? extends GrantedAuthority> authorities;  //用户的权限集合//省略构造方法//省略set方法//省略get方法(即接口UserDetails的方法)}

我们就是写了一个适应于UserDetails的java POJO类,所谓的 UserDetails接口实现就是一些get方法。get方法由Spring Security调用,我们通过set方法或构造函数为 Spring Security提供UserDetails数据。


实现UserDetailsService接口

实现UserDetailsService接口

@Component
public class MyUserDetailsService implements UserDetailsService{@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//这里从数据库sys_user表里面查询实体类对象。loadUser方法可使用Mybatis或JDBC或JPA自行实现。SysUser sysUser =  loadUser(username);   // 判断用户是否存在if(user == null)  {  throw  new  UsernameNotFoundException("用户名不存在");  }//从数据库该用户所有的角色信息,所有的权限标志//遍历所有的ROLE角色及所有的Authority权限(菜单、按钮)。//用逗号分隔他们的唯一标志,具体过程自行实现。sysUser.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_AMIN , system:user:delete"));//sysUser.setAccountNonLocked(true或false);return sysUser;}}

通常数据库表sys_user字段要和SysUser属性一一对应,比如username、password、enabled。但是比如accountNonLocked字段用于登录多次错误锁定,但我们一般不会在表里存是否锁定,而是存一个锁定时间字段。通过锁定时间是否大于当前时间判断账号是否锁定,所以实现过程中可以灵活做判断并用好set方法,不必拘泥于一一对应的形式。

角色是一种特殊的权限,在Spring Security我们可以使用hasRole(角色标识)表达式判断用户是否具有某个角色,决定他是否可以做某个操作;通过hasAuthority(权限标识)表达式判断是否具有某个操作权限。


本文小结

至此,我们将系统里面的所有的用户、角色、权限信息都通过UserDetailsService和UserDetails告知了Spring Security。但是多数朋友可能仍然不知道该怎样实现登录的功能,其实剩下的事情很简单了:

  • 写一个登录界面,写一个登录表单,表单使用post方法提交到默认的/login路径
  • 表单的用户名、密码字段名称默认是username、password。
  • 写一个登录成功之后的跳转页面,比如index.html

然后把这些信息通过配置方式告知Spring Security ,以上的配置信息名称都可以灵活修改。

SpringSecurity动态加载用户角色权限实现登录及鉴权相关推荐

  1. Day239.RBAC模式、动态加载用户权限资源规则数据规则、【记住我】注销多次登录图片验证码session验证码验证功能 -springsecurity-jwt-oauth2

    1.RBAC权限管理模型 一.RBAC权限模型简介 RBAC权限模型(Role-Based Access Control)即:基于角色的权限控制.模型中有几个关键的术语: 用户:系统接口及功能访问的操 ...

  2. 动态加载用户控件的怪问题

    动态加载用户控件的时候,会因为调用一些控件的一些属性和方法而造成控件命名混乱. 因为add 一个用户控件或者 loadcontrol 的时候 如果没有指定控件的id,clientid,那么它会初始id ...

  3. 使用RenderControl方法实现动态加载用户控件

    nsus.NET相信很多网友们均会动态加加载用户控件.如Insus.NET以前写的博文: http://www.cnblogs.com/insus/archive/2012/04/16/2451085 ...

  4. Asp.net2.0动态加载用户控件的三种方法

    方法一: 直接拖放的用户控件 <!--这是某个aspx页--> ..... <%@ Register Src="TestControl.ascx" TagName ...

  5. 读书笔记:《Aspx开发200问》——如果实现动态加载用户空间

    (1)创建一个名为UserControlExample.asc的用户控件 (2)创建一个UserControlTest.aspx的页面 <%@ Page language="c#&qu ...

  6. Asp.net 2.0 动态加载其他子目录用户控件问题

    通常我们要在程序中动态加载用户控件: 方法很简单直接在程序里键入: (usercontrol type)a = (usercontrol type)Page.LoadControl("~/x ...

  7. 铵钮提交事件PostBack之后,一些动态加载的物件丢失

    今早起来,发现skype有网友留言,情况大约如下,不过Insus.NET还是先感谢网友的测试. http://www.cnblogs.com/insus/p/3193619.html  如果你有看此篇 ...

  8. vue 动态修改后端请求_vue-element-admin实战 | 第二篇: 最小改动接入后台实现根据权限动态加载菜单...

    一. 前言 本篇基于 有来商城 youlai-mall微服务项目,通过对vue-element-admin的权限菜单模块理解个性定制其后台接口,实现对vue-element-admin工程几乎不做改动 ...

  9. vue系统权限(动态加载路由方式)

    目录 1.注册vue-router 2.声明 默认路由 和权限路由 3.用vuex实现全局登录.退出登录等方法 4.用vuex模块单独写权限路由的判断 5.监听路由跳转实现动态加载权限菜单 需要用到动 ...

最新文章

  1. php-fpm 进程管理
  2. linux 知识汇总
  3. 精选案例 | “虫虫音乐”如何做到搜索CTR提高150%
  4. 【java】父类与子类的引用赋值关系
  5. JQuery模拟boostrap模态框效果
  6. 如何在python3环境下的Django中使用MySQL数据库
  7. VMware虚拟化技术培训(6) 虚拟网络和虚拟存储
  8. 记录:Linux 设置文件夹 0777 权限失效问题
  9. node.js windows解压版安装与配置
  10. 坦克采样器加钢琴鼓组弦乐打击音源-IK Multimedia SampleTank 4 v4.1.4 + Library
  11. 手机酒店预订的革命之作——全新艺龙无线手机客户端测评
  12. 教师不能错过的三款教学必备工具
  13. HTTP VS HTTPS
  14. 动态规划:钢条切割问题
  15. 已知x,h求y(信号处理)
  16. 学习笔记(34):Python 面试100讲(基于Python3.x)-用正则表达式分别提取电话号的区号、电话号和分机号...
  17. 一个普通玩家眼中的网博会
  18. python爬虫(19)爬取论坛网站——网络上常见的gif动态图
  19. 用 Flutter 实现 PageView 指示器
  20. 大数据与Hadoop之间是什么关系

热门文章

  1. bootstrap-fileinput 简单使用
  2. 企业局域网内如何跨网安全传输数据
  3. 架构中的设计原则之单一职责原则 - 《java开发技术-在架构中体验设计模式和算法之美》...
  4. 检测浏览器是否支持WebSocket
  5. 标准日本语 05_003
  6. Silverlight C# 游戏开发:关于精灵for Silverlight容器
  7. 存储网络系统的瓶颈分析以及瓶颈的解决之道
  8. 2018-2019-1 20189218《Linux内核原理与分析》第九周作业
  9. ESLint使用文档
  10. Spring Boot flyway的启动时机比较早