温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-09-28 11:42:06 来源:亿速云 阅读:88 作者:小新 栏目:编程语言

这篇文章将为大家详细讲解有关如何使用SpringSecurity动态加载用户角色权限实现登录及鉴权功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

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

在本号之前的文章中,已经介绍了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接口

@Componentpublic 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 ,以上的配置信息名称都可以灵活修改。

关于“如何使用SpringSecurity动态加载用户角色权限实现登录及鉴权功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI