热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

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

这篇文章主要介绍了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<&#63; 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<&#63; 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登录认证模式》。

总结

以上所述是小编给大家介绍的SpringSecurity动态加载用户角色权限实现登录及鉴权功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!


推荐阅读
  • 本文为初学者提供了一条清晰的学习路线,帮助他们逐步成长为优秀的Web开发人员。通过十个关键步骤,涵盖从基础到高级的各个方面,确保每位学习者都能找到适合自己的学习方向。 ... [详细]
  • Gty的二逼妹子序列 - 分块与莫队算法的应用
    Autumn 和 Bakser 正在研究 Gty 的妹子序列,但遇到了一个难题。他们希望计算某个区间内美丽度属于 [a, b] 的妹子的美丽度种类数。本文将详细介绍如何利用分块和莫队算法解决这一问题。 ... [详细]
  • SvpplyTable: 实现可扩展和可折叠的菜单动画
    SvpplyTable 是一个示例项目,旨在实现类似 Svpply 应用程序中的可扩展和可折叠的菜单动画效果。该项目托管在 GitHub 上,地址为 https://github.com/liuminqian/SvpplyTable。 ... [详细]
  • 本文介绍了一种使用CSS3和jQuery实现的35款SVG图标加载动画。这些动画不仅视觉效果出色,还能提升用户体验。通过本文,您可以了解如何在项目中应用这些动画。 ... [详细]
  • 本文介绍了如何在 Qt 应用程序中实现状态栏、浮动窗口(铆接部件)和中心部件。通过简单的代码示例,详细解释了每个组件的创建和设置方法。 ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • 本文介绍了如何使用Postman构建和发送HTTP请求,包括四个主要部分:方法(Method)、URL、头部(Headers)和主体(Body)。特别强调了Body部分的重要性,并详细说明了不同类型的请求体。 ... [详细]
  • 本文介绍了 Confluence 6 中使用的其他 Cookie,这些 Cookie 主要用于存储产品的基本持久性和用户偏好设置,以提升用户体验。 ... [详细]
  • Bootstrap 插件使用指南
    本文详细介绍了如何在 Web 前端开发中使用 Bootstrap 插件,包括自动触发插件的方法、插件的引用方式以及具体的实例。 ... [详细]
  • iOS snow animation
    CTSnowAnimationView.hCTMyCtripCreatedbyalexon1614.Copyright©2016年ctrip.Allrightsreserved.# ... [详细]
  • 如何解决TS1219:实验性装饰器功能可能在未来版本中更改的问题
    本文介绍了两种方法来解决TS1219错误:通过VSCode设置启用实验性装饰器,或在项目根目录下创建配置文件(jsconfig.json或tsconfig.json)。 ... [详细]
  • 解决MAC远程桌面连接证书无效问题
    本文介绍如何解决在使用MAC远程桌面连接时遇到的“证书或相关链无效”错误。通过详细步骤和专业建议,帮助用户顺利连接远程桌面。 ... [详细]
  • 使用Tkinter构建51Ape无损音乐爬虫UI
    本文介绍了如何使用Python的内置模块Tkinter来构建一个简单的用户界面,用于爬取51Ape网站上的无损音乐百度云链接。虽然Tkinter入门相对简单,但在实际开发过程中由于文档不足可能会带来一些不便。 ... [详细]
  • 本文探讨了 Canvas 元素在不同尺寸设置下出现变形失真的原因,并详细解释了 HTML 尺寸和 CSS 尺寸的区别及其对视觉效果的影响。 ... [详细]
  • MongoDB核心概念详解
    本文介绍了NoSQL数据库的概念及其应用场景,重点解析了MongoDB的基本特性、数据结构以及常用操作。MongoDB是一个高性能、高可用且易于扩展的文档数据库系统。 ... [详细]
author-avatar
苏佡挖图组糖最棒
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有