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登录认证模式》。

总结

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

(0)

相关推荐

  • Spring Security OAuth2集成短信验证码登录以及第三方登录

    前言 基于SpringCloud做微服务架构分布式系统时,OAuth2.0作为认证的业内标准,Spring Security OAuth2也提供了全套的解决方案来支持在Spring Cloud/Spring Boot环境下使用OAuth2.0,提供了开箱即用的组件.但是在开发过程中我们会发现由于Spring Security OAuth2的组件特别全面,这样就导致了扩展很不方便或者说是不太容易直指定扩展的方案,例如: 图片验证码登录 短信验证码登录 微信小程序登录 第三方系统登录 CAS单点登录

  • 话说Spring Security权限管理(源码详解)

    最近项目需要用到Spring Security的权限控制,故花了点时间简单的去看了一下其权限控制相关的源码(版本为4.2). AccessDecisionManager spring security是通过AccessDecisionManager进行授权管理的,先来张官方图镇楼. AccessDecisionManager AccessDecisionManager 接口定义了如下方法: //调用AccessDecisionVoter进行投票(关键方法) void decide(Authent

  • Spring Boot整合Spring Security的示例代码

    本文讲述Spring Boot整合Spring Security在方法上使用注解实现权限控制,使用自定义UserDetailService,从MySQL中加载用户信息.使用Security自带的MD5加密,对用户密码进行加密.页面模板采用thymeleaf引擎. 源码地址:https://github.com/li5454yong/springboot-security.git 1.引入pom依赖 <parent> <groupId>org.springframework.boot

  • Spring Security Oauth2.0 实现短信验证码登录示例

    本文介绍了Spring Security Oauth2.0 实现短信验证码登录示例,分享给大家,具体如下: 定义手机号登录令牌 /** * @author lengleng * @date 2018/1/9 * 手机号登录令牌 */ public class MobileAuthenticationToken extends AbstractAuthenticationToken { private static final long serialVersionUID = SpringSecur

  • SpringBoot + Spring Security 基本使用及个性化登录配置详解

    Spring Security 基本介绍 这里就不对Spring Security进行过多的介绍了,具体的可以参考官方文档 我就只说下SpringSecurity核心功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) 基本环境搭建 这里我们以SpringBoot作为项目的基本框架,我这里使用的是maven的方式来进行的包管理,所以这里先给出集成Spring Security的方式 <dependencies> ... <dependency> <groupI

  • Spring security实现登陆和权限角色控制

     随笔简介 1.spring版本:4.3.2.RELEASE+spring security 版本:4.1.2.RELEASE(其它不做说明) 2.所展示内容全部用注解配置 3.springmvc已经配置好,不作说明 4.会涉及到springmvc,spel,el的东西,不熟悉的同学可以先去看一下这方面内容,特别是springmvc 首先想一下,登陆需要什么,最简单的情况下,用户名,密码,然后比对数据库,如果吻合就跳转到个人页面,否则回到登陆页面,并且提示用户名密码错误.这个过程中应该还带有权限

  • spring security自定义认证登录的全过程记录

    spring security使用分类: 如何使用spring security,相信百度过的都知道,总共有四种用法,从简到深为: 1.不用数据库,全部数据写在配置文件,这个也是官方文档里面的demo: 2.使用数据库,根据spring security默认实现代码设计数据库,也就是说数据库已经固定了,这种方法不灵活,而且那个数据库设计得很简陋,实用性差: 3.spring security和Acegi不同,它不能修改默认filter了,但支持插入filter,所以根据这个,我们可以插入自己的f

  • SpringBoot+SpringSecurity处理Ajax登录请求问题(推荐)

    最近在项目中遇到了这样一个问题:前后端分离,前端用Vue来做,所有的数据请求都使用vue-resource,没有使用表单,因此数据交互都是使用JSON,后台使用Spring Boot,权限验证使用了Spring Security,因为之前用Spring Security都是处理页面的,这次单纯处理Ajax请求,因此记录下遇到的一些问题.这里的解决方案不仅适用于Ajax请求,也可以解决移动端请求验证. 创建工程 首先我们需要创建一个Spring Boot工程,创建时需要引入Web.Spring S

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

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

  • asp.net动态加载用户控件,关于后台添加、修改的思考

    看下下面这个典型的后台(比较粗糙):说实在,我很厌倦全部用.aspx文件去做,比如"友情连接"这个模块,就有"添加友情连接""修改友情连接""友情连接列表",简单的话,可以把"添加""修改"合成一个文件.每次都去建立一个.aspx文件.我现在的想法是用"用户控件+配置文件"去实现,虽然文件数目可能不会少很多.但在编程到一定地步,我想大家会有跟我一样的想法. 首先需要涉

  • 动态加载用户控件至DataList并为用户控件赋值实例演示

    为了实现这个演示,Insus.NET使用通用的新闻例子,它类别(目录)以及文章.在一个页面,显示所有类别,每个目录下显示最新几条新闻. 效果如下: 目录是用DataList控件显示,而文章标题列表是一个用户控件显示,这个用户控件将动态被加入至DataList. 复制代码 代码如下: View Code <asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_Item

  • ASP.NET动态加载用户控件的实现方法

    第一步:例如用户控件放在MyList.Ascx,然后其Control指令是: 复制代码 代码如下: <%@ Control Language="C#" AutoEventWireup="true" CodeFile="ViewComment.ascx.cs" Inherits="Control_ViewComment"%> 这时候已经有了Inherits,自带了ClassName就是其名称,如果没有,则必须创建Cl

  • Asp.net 动态加载用户自定义控件,并转换成HTML代码

    如果页面单纯的使用js来创建,要写大量的代码,而且不直观. 在asp.net中,其实我们可以创建用户自定义控件,通过Ajax请求返回用户自定义控件HTML代码. 复制代码 代码如下: public static string RangerUsControl(string controlName) { StringBuilder build = new StringBuilder(); HtmlTextWriter htmlWriter = new HtmlTextWriter(new Strin

  • .NET动态加载用户控件并传值的方法

    ASPX.CS里的代码: 复制代码 代码如下: UserControl uc = (UserControl)LoadControl(actionOne[1].ToString());uc.GetType().GetProperty("cid").SetValue(uc, cid.ToString(), null);//主要就在这里,这里是添加属性,并赋值.uc.GetType().GetProperty("aid").SetValue(uc, id.ToString

  • SpringSecurity实现动态加载权限信息的方法

    ①数据库中资源与角色对应关系,以及角色和用户对应关系如下图所示: ②实现FilterInvocationSecurityMetadataSource类 (1)List<Menu> menus = menuService.getMenusWithRoles();这个是你自己的资源对应角色的查询方法. (2)重写的support方法都返回true @Configuration public class MyFilterInvocation implements FilterInvocationSe

  • AngularJS动态加载模块和依赖的方法分析

    本文实例讲述了AngularJS动态加载模块和依赖的方法.分享给大家供大家参考,具体如下: 前言 由于AngularJS是单页面应用框架,在正常的情况下,会在访问页面的时候将所有的CSS.JavaScript文件都加载进来.文件不多的时候,页面启动速度倒不会影响太多.但是一旦文件数太多或者加载的第三方库比较大的时候,就会影响页面启动速度.因此对于应用规模大.文件数比较多或者加载的第三方库比较大的时候,采用动态加载JS或者动态加载模块会极大提升页面的启动速度.本文将介绍如何利用ocLazyLoad

  • 动态加载权限管理模块中的Vue组件

    本文我们主要来聊聊登录以及组件的动态加载. 登录状态保存 当用户登录成功之后,需要将当前用户的登录信息保存在本地,方便后面使用.具体实现如下: 登录成功保存数据 在登录操作执行成功之后,通过commit操作将数据提交到store中,核心代码如下: this.postRequest('/login', { username: this.loginForm.username, password: this.loginForm.password }).then(resp=> { if (resp &

  • Spring Boot集成Shiro实现动态加载权限的完整步骤

    一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .uri 权限后,后端动态分配权限,用户无需在页面重新登录才能获取最新权限,一切权限动态加载,灵活配置 基本环境 spring-boot 2.1.7 mybatis-plus 2.1.0 mysql 5.7.24 redis 5.0.5 温馨小提示:案例demo源码附文章末尾,有需要的小伙伴们可参考哦 ~

随机推荐