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

很多人觉得Spring Security实现登录验证很难,我最开始学习的时候也这样觉得。因为我好久都没看懂我该怎么样将自己写的用于接收用户名密码的Controller与Spring Security结合使用,这是一个先入为主的误区。后来我搞懂了:根本不用你自己去写Controller。你只需要告诉Spring Security用户信息、角色信息、权限信息、登录页是什么?登陆成功页是什么?或者其他有关登录的一切信息。具体的登录验证逻辑它来帮你实现。
一、动态数据登录验证的基础知识
在本号之前的文章中,已经介绍了Spring Security的formLogin登录认证模式,RBAC的权限控制管理模型,并且针对Spring Security的登录认证逻辑源码进行了解析等等。我们所有的用户、角色、权限信息都是在配置文件里面写死的,然而在实际的业务系统中,这些信息通常是存放在RBAC权限模型的数据库表中的。下面我们来回顾一下其中的核心概念:
- RBAC的权限模型可以从用户获取为用户分配的一个或多个角色,从用户的角色又可以获取该角色的多种权限。通过关联查询可以获取某个用户的角色信息和权限信息。
- 在源码解析的文章中,我们知道如果我们不希望用户、角色、权限信息写死在配置里面。我们应该实现UserDetails与UserDetailsService接口,从而从数据库或者其他的存储上动态的加载这些信息。
以上是对一些核心的基础知识的总结,如果您对这些知识还不是很清晰,建议您先往下读本文。如果看完本文仍然理解困难,建议您翻看本号之前的文章。
二、UserDetails与UserDetailsService接口
- UserDetailsService接口有一个方法叫做loadUserByUsername,我们实现动态加载用户、角色、权限信息就是通过实现该方法。函数见名知义:通过用户名加载用户。该方法的返回值就是UserDetails。
- UserDetails就是用户信息,即:用户名、密码、该用户所具有的权限。
下面我们来看一下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 接口
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接口
@Component
public class MyUserDetailsService implements UserDetailsService{
@Override
public 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 ,以上的配置信息名称都可以灵活修改。如果您不知道如何配置请参考本号之前的文章《formLogin登录认证模式》。
期待您的关注
- 向您推荐博主的系列文档:《手摸手教您学习SpringBoot系列-16章97节》
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
SpringSecurity动态加载用户角色权限实现登录及鉴权的更多相关文章
- Windows.Forms Panel 动态加载用户控件 UserControl
创建好一个Windows Forms程序,在创建好的程序中Form1添加一个Panel控件 如图:
- ASP.NET动态加载用户控件的方法
方法是使用LoadControl方法,根据用户控件的相对路径,动态生成用户控件对象 用户控件 public class UserControlA :UserControl { public UserC ...
- [ASP.NET]asp.net动态加载用户控件
用户控件 // 用户控件源码 namespace wzjr.control { public partial class Topic : System.Web.UI.UserControl { pub ...
- .NET动态加载用户控件并传值的方法
ASPX.CS里的代码: VoteChat.GetType().GetProperty("vid").SetValue(VoteChat, model.id.ToString(), ...
- Winform开发框架之客户关系管理系统(CRM)的开发总结系列4-Tab控件页面的动态加载
在前面介绍的几篇关于CRM系统的开发随笔中,里面都整合了多个页面的功能,包括多文档界面,以及客户相关信息的页面展示,这个模块就是利用DevExpress控件的XtraTabPage控件的动态加载实现的 ...
- 铵钮提交事件PostBack之后,一些动态加载的物件丢失
今早起来,发现skype有网友留言,情况大约如下,不过Insus.NET还是先感谢网友的测试.http://www.cnblogs.com/insus/p/3193619.html 如果你有看此篇博 ...
- Asp.Net Core 项目实战之权限管理系统(8) 功能菜单的动态加载
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- shiro不重启动态加载权限
最近一朋友让我帮他做一个后台权限管理的项目.我就在我原来的项目加加改改但是还是不理想,查了不少资料也走了不了弯路...... shiro基本的配置我就不多说了这个很简单自己查查资料就完成----下面是 ...
- SpringBoot集成Shiro 实现动态加载权限
一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...
随机推荐
- 数据结构(四十一)多路查找树(B树)
一.多路查找树的背景 前面所讨论的查找算法都是在内存中进行的,它们适用于较小的文件,而对于较大的.存放在外存储器上的文件就不合适了,对于此类大规模的文件,即使是采用了平衡二叉树,在查找效率上仍然较低. ...
- day3-02 python入门之基本的数据类型
目录 一.整型(int) 二.浮点型(float) 三.字符串类型(str) 字符串在python2和python3中的细微区别 四.复数 五.列表(list) 六.数据字典(dict) 定义方式 七 ...
- Linux安装h2数据库
安装H2数据库,为后面mybatisplus3J集成做铺垫 下载jar包 https://pan.baidu.com/s/1tPZQH5tum1CheDxumcN24g 运行jar包 [root@to ...
- Vue实例与模板语法
VUE基础使用方法 一.安装 1.NPM 在用 Vue 构建大型应用时推荐使用 NPM 安装[1].NPM 能很好地和诸如 webpack 或 Browserify 模块打包器配合使用.同时 Vue ...
- vue中改变数组的值视图无变化
今天开发的时候遇到一个多选取消点击状态的,渲染的时候先默认都选中,然后可以取消选中,自建了一个全为true的数组,点击时对应下标的arr[index]改为false,数据改变了状态没更新,突然想起来单 ...
- 学习笔记43_T4模板
新建-文本模板(后缀为.tt) <#@ template debug="false" hostspecific="false" language=&qu ...
- 学习笔记25_MVC前台API
**当请求url的规则有所改变时,前台的所有超链接的href都得改,为了避免多处修改,可以href = "< %=url.Action("Controller",& ...
- C/C++ return *this和return this的区别
首先我们知道~ class Test { public: Test() { return this; //返回的当前对象的地址 } Test&() { return *this; //返回的是 ...
- jmeter-手机号验证注册登录
1.测试计划->线程组 2.首先获取需要注册的手机号,获取手机号的方式如下 (1)使用配置元件导入需要注册的手机 ·右键线程组-->配置元件-->CSV数据文件设置,如图: (2)使 ...
- python学习之【第十四篇】:Python中的装饰器
1.什么是装饰器? 器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 2.遵循的原则 装饰器必须遵循以下两个原则: 不修改被装饰函数的源代码(开放封 ...