Springboot +spring security,基于默认数据库模型实现授权

一.简介

上一篇文章中讲解了如何基于内存模型来实现授权,在这种模型里,用户的信息是保存在内存中的。但是,保存在内存中的信息,是无法持久化的,也就是程序一旦关闭,或者断电等情况发生,内存中的信息就丢失了,所以这种方式并不适用于生产环境。

那么肯定就要把用户信息持久化, 持久化到数据库,这边文章中采用的是MySQL数据库。

二.JdbcUserDetailsManager类

在数据库中创建并保存用户及角色信息,Spring Security给我们提供了另一个UserDetailsService的实现子类,就是JdbcUserDetailsManager。其中JdbcUserDetailsManager类的关系结构如下图所示:
在这里插入图片描述
从上图中,可以看到JdbcUserDetailsManager的直接父类是JDBCDaoSuport,利用JdbcUserDetailsManager可以帮助我们以JDBC的方式对接数据库进行增删改查等操作。它内部设定了一个默认的数据库模型,只要遵从这个模型,我们就可以很方便的实现在数据库中创建用户名和密码、角色等信息,但是灵活性不足。

三. 创建SpringSecurity项目

参考之前的文章,这边不做叙述。

四. 基于默认数据库模型实现授权

3.1创建测试接口

在开始授权代码之前,先创建3个用于测试的Web接口,分别供3个不同的用户角色来进行操作。

3.1.1创建/admin/hello接口:

AdminController 类代码如下:

@RestController
@RequestMapping("/admin")
public class AdminController {@GetMapping("/hello")public String hello() {return "hello, admin";}
}

3.1.2创建/user/hello接口:

UserController 类代码如下:

@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("hello")public String hello() {return "hello, user";}
}

3.1.3创建/visitor/hello接口:

VisitorController 类代码如下:

@RestController
@RequestMapping("/visitor")
public class VisitorController {@GetMapping("/hello")public String hello() {return "hello, visitor";}
}

对于以上三个接口,做如下解释:

  1. /visitor/hello 任何人都可以访问;
  2. /admin/hello 具有 admin 角色的人才能访问;
  3. /user/hello 具有 user 角色的人才能访问;
  4. 所有 user 角色能够访问的接口资源,admin 角色也都能够访问。

4.2准备数据库

既然要操作数据库,那肯定得先建库建表,JdbcUserDetailsManager本身就给我们提供了对应的数据库脚本模型,这个数据库脚本模型保存在如下位置:

org/springframework/security/core/userdetails/jdbc/users.ddl

截图如下:
在这里插入图片描述
直接去这个对应的位置下,找到这个数据库脚本文件打开即可。

当打开这个users.ddl文件,可以看到如下内容,会发现其中有2个建表语句,分别是创建了users表和authorities表,并且在authorities表中创建了唯一索引。代码如下:

create table users(username varchar_ignorecase(50) not null primary key,password varchar_ignorecase(500) not null,enabled boolean not null);create table authorities (username varchar_ignorecase(50) not null,authority varchar_ignorecase(50) not null,constraint fk_authorities_users foreign key(username) references users(username));create unique index ix_auth_username on authorities (username,authority);

放到navicat中,创建即可。

注意:

上面的建表脚本中,有一种数据类型 varchar_ignorecase,这个是针对 HSQLDB 数据库创建的,但是我们使用的 MySQL 数据库并不支持这种数据类型,所以这里需要手动将这个数据类型改为 varchar。

4.3配置资源访问权限

先定义一个SecurityConfig配置类,在其中配置对资源的访问控制,创建一个UserDetailsService实例,并在其中配置,生成存储用户和角色信息,代码如下:

@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER").antMatchers("/app/**").permitAll().anyRequest().authenticated().and().formLogin().permitAll();}/***************************************在默认的数据库中创建用户和角色****************************************************/@Autowiredprivate DataSource dataSource;@Beanpublic UserDetailsService createUserDetailService() {JdbcUserDetailsManager manager = new JdbcUserDetailsManager();manager.setDataSource(dataSource);if (!manager.userExists("user")) {manager.createUser(User.withUsername("user").password("123").roles("USER").build());}if (!manager.userExists("admin")) {manager.createUser(User.withUsername("admin").password("123").roles("USER", "ADMIN").build());}return manager;}@Beanpublic PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}}

4.4代码释义

要针对createUserDetailService()方法进行解释。

  1. 在这个方法中,我们首先构建一个 JdbcUserDetailsManager 实例对象,并给 JdbcUserDetailsManager 实例添加一个 DataSource 对象。
  2. 接下来调用 userExists()方法 判断用户是否存在,如果不存在,就创建一个新的用户出来(因为每次项目启动时这段代码都会执行,所以加一个判断,避免重复创建用户)。
  3. 用户的创建方法和我们之前 InMemoryUserDetailsManager 中的创建用户的方法基本一致。

以上就是我们基于默认的数据库模型实现的对用户及角色的操作,之所以可以实现,就是因为在UserDetailsManager这个父接口中,定义了如下方法,这些方法在子类中都有具体的实现。截图如下:
在这里插入图片描述
可以看到UserDetailsManager类中,提供了创建、修改、删除、判断用户是否存在的方法,和修改用户密码的方法。

在JdbcUserDetailsManager这个实现子类中,已经定义好了users与authorities表对应的CRUD语句,所以我们直接调用相关方法即可实现对用户及角色的管理。另外我们在特殊情况下,也可以自定义这些SQL语句,如有需要,调用对应的setXxxSQL()方法即可。
在这里插入图片描述

五.验证

项目启动起来,然后以不同的身份登录进来,分别访问不同的接口,当某个用户在不具备相应角色时,会出现403提示信息。只有具有相应的角色权限时,才可以访问对应的接口。截图如下:
在这里插入图片描述

当我们使用Spring Security默认的数据库模型来操作实现用户授权时,存在灵活性不足的问题,因为我们必须按照源码规定的方式去建库建表。而我们真正开发时,用户角色等表肯定是根据自己的项目需求来单独设计的,所以真正开发时,我们有必要进行用户及角色表的自定义设计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/351797.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

如何给apk安装包去毒,避免被识别为病毒和木马

本文来源:安卓修改大师 如果您的应用经常被识别为病毒或者木马,将大大影响应用的推广,更影响您的收益。各种安卓平台的安全软件的监管规则越来越严格,您的应用可能一不小心就会进入病毒库,被识别为有害应用。有没有更…

中了计算机病毒改怎么办,计算机中病毒了怎么办?清除计算机病毒方法有哪些...

计算机中病毒了怎么办?清除计算机病毒方法有哪些。当我们的计算机中了病毒是,该怎么样去清除呢?下面由学习啦小编给你做出详细的清除计算机病毒方法介绍!希望对你有帮助! 清除计算机病毒方法一: 1、全盘搜该文件,删除;[startup.x…

安卓现盗号木马 威胁网银盗刷

最近,某移动安全实验室捕获到一类高度危险的微信盗号木马,多个安卓手机应用中捆绑了该木马,手机中毒后微信帐号会被盗,严重威胁微信钱包及微信关联的网银资金安全,目前已有上千名用户受害。 一个不幸中的万幸是&#x…

SpringBoot3-基础配置和多环境开发

1. 配置文件格式 提供三种属性配置方式,当三个配置文件都有,加载顺序从前至后 示例第二种(主要也是用这个): 2. yaml格式 3. yaml读取数据格式的三种方式 第一种,使用Value读取单一属性数据 Value("${…

病毒木马防御与分析实战

《病毒木马防御与分析》系列以真实的病毒木马(或恶意程序)为研究对象,通过现有的技术手段对其分析,总结出它的恶意行为,进而制定出相应的应对方法,对其彻底查杀。当然,因为我个人水平的有限&…

病毒木马防御与分析实战

《病毒木马防御与分析》系列以真实的病毒木马(或恶意程序)为研究对象,通过现有的技术手段对其分析,总结出它的恶意行为,进而制定出相应的应对方法,对其彻底查杀。当然,因为我个人水平的有限&…

病毒木马防御与分析

病毒木马防御与分析 病毒包和工具包下载:Github 一.前言二.建立对手动查杀病毒技术的正确认识 1.病毒分析方法2.病毒查杀步骤3.必备知识 * 1) 熟悉windows系统进程 * 2) 熟悉常见端口与进程对应关系 * 3) 熟悉windows自带系统服务 * 4) 熟悉注册表启动项位置三.详解Windows随机…

程序员大专毕业,月薪2w是什么体验?

在这个数据驱动的时代,大数据行业的发展前景也非常广阔,我相信我的未来会越来越光明 01 开始学习 是迈向前方的第一步 我是三月,一个来自小城市的大专毕业生。现在在杭州一家公司做大数据开发工程师,目前薪资是20k*13。 我本身…

MySQL 自增列使用上的一些 “坑”

文章目录 前言1. 自增列空洞1.1 手动指定2.2 分配未使用 2. 自增列监控2.1 sys 库监控2.2 通用查询 3. 一些 BUG3.1 重启失效3.2 冲突问题 前言 MySQL 的规范中,一般都会建议表要有主键,常使用自增列作为主键字段,这和 MySQL 属于聚簇索引表…

SQL——事务

🎈 什么是事务 💧 概念 事务是用于保证数据的一致性,它由一组相关的DML(增、删、改)语句,该组的DML语句要么全部成功,要么全部失败。使用事务可以确保数据库的一致性和完整性,避免数据出现异常…

蓝屏代码0x00000074

前台电脑系统是win7,用着用着突然蓝屏(代码0x00000074),网上都说是内存条或者选择最近一次正确的配置,但是我发现进bios都识别不到固态硬盘,以为硬盘坏了就换了一个就可以了,但是用了一星期不到…

0x0000007B是什么意思?解决方案

0x0000007b电脑蓝屏通常情况是硬盘的存储控制器驱动加载错误导致故障。对于这种情况就要有相应解决措施,下面来看看具体解决方法。 导致驱动加载错误的情况可能有以下三种情况: 1.无法自动识别硬盘控制器: 使用非正版的个别操作系统光盘&…

问题解决:应用程序错误0xc00007b

1. 问题出现 在安装软件lightroom的时候,出现了应用程序错误0xc00007b,程序无法打开,尝试了好些办法,最终是安装一个插件解决了问题。 2. 问题解决 安装aio-runtimes软件,里面包含一些基本软件所需要的库&#xff0c…

应用程序无法正常启动(0xc000007b)的解决办法

应用程序无法正常启动(0xc000007b)的解决办法。 有时候我们启动程序会发现以下错误,如图所示: 解决方法1: (1)根据下图指示,以管理员身份打开CMD (2)输入…

如何解决错误0×80071AC3

前几天我在机房敲百例的时候,敲完了想把文件夹移动到我的U盘里去,结果出现了这种情况 上面说运行chkdsk并重试,我运行了一下,没什么反应,我就想既然不能移动文件夹了,那就试试能不能移动文档好了&#xff0…

应用程序无法正常启动0xc000007b win7

1. 一开始报错 下载dll放到同级目录后报下一个错误。 (这里注意:搜索的时候就发现大多数dll都是 vc_runtime 140 没有d,d表示debug。同事指点:使用vscode生成解决方案时要用release模式,不是debug模式,这也…

蓝屏stop:0x000000007B (oxf78aa524,Oxcooooo34

神舟飞天超级本安装键盘后提示错误,开机后,反复按f2,进入bios,高级SATA选项,发现我的默认是AHCI的模式我设置为IDE,按f4保存退出后正常了.

电脑运行应用程序出现0xc000007b的解决方法

在我们使用Windows操作系统的计算机时,双击运行程序,它无法运行而且还会出现一个这样的对话框(如下图),总之程序就是运行不了,让人很头疼,这次教大家如何解决这个问题。 出现这样的问题,是电脑里面的几个文…

无法正常启动0xc000007b的解决方法

最近在我的电脑上用VS10-x64 release编译好了一个软件,用了VC,openCV以及其他的库,在我们已经装了VS10的电脑上运行都没有问题,但是在一台全新的电脑上安装上我发布的软件就出问题了。客户要求我们不能装VS10软件,于是我们装了VC1…

Spring-data-jpa最全的查询语法总结,直入超神

🤵‍♂️ 个人主页:香菜的个人主页 ✍🏻作者简介:csdn 认证博客专家,游戏开发领域优质创作者,华为云享专家,2021年度华为云年度十佳博主 🐋 希望大家多多支持,我们一起进步&#xff…