动力节点Springsecurity笔记01-05认证入门

news/2024/12/27 9:46:13/

1 问题 如何保护我们的程序?

1.1 创建code目录

目的:后面的security工程均在此目录下学习
创建code目录,并使用idea打开

1.2 不使用安全框架的springboot web程序

1.2.1 新建子模块springboot-01-hello

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAeASGKn-1681958373972)(https://cdn.nlark.com/yuque/0/2023/png/32441366/1681955131092-bbc460d1-dc01-4b6a-bdf3-38a7a06ee7be.png#height=303&width=415)]

1.2.2 添加依赖和maven插件等

pom.xml 中部分内容如下,此处使用bootpom模板创建并粘贴

<parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.6.13</version><relativePath/> <!-- lookup parent from repository -->
</parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><java.version>1.8</java.version>
</properties><dependencies><!--springboot web 程序 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--springboot 单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--自动生成get、set和日志对象的lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

1.2.3 新建启动类

com.powernode包下新建启动类Application,可以使用bootmain模板,学员自行创建

1.2.4 新建三个controller

com.powernode.controller包下新建三个controller
学生

@RestController
@RequestMapping("/student")public class StudentController {@GetMapping("/query")public String queryInfo(){return "I am a student,My name is Eric!";}
} 

教师

@RestController
@RequestMapping("/teacher")public class TeacherController {@GetMapping("/query")public String queryInfo(){return "I am a teacher,My name is Thomas!";}} 

管理员

@RestController@RequestMapping("/admin")public class AdminController {@GetMapping("/query")public String queryInfo(){return "I am a administrator, My name is Obama!";}} 

1.2.5 启动程序

启动程序的快捷键:Ctrl+Shift+F10

1.2.6 访问程序

通过浏览器访问程序

| http://localhost:8080/student/query
http://localhost:8080/teacher/query

http://localhost:8080/admin/query

通过curl访问(可以使用git bash)

| # curl 默认发出get请求,下面可以省略 -X GET选项

curl -X GET localhost:8080/teacher/query

返回效果如下:

curl 的使用可以作为扩展学习(不讲,学员自学

| curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是命令行(Command Line)下的 URL 工具的意思。
它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。

参考学习网站:
https://catonmat.net/cookbooks/curl
https://www.ruanyifeng.com/blog/2019/09/curl-reference.html
https://www.ruanyifeng.com/blog/2011/09/curl.html
https://blog.csdn.net/angle_chen123/article/details/120675472

1.2.7 结论

此示例说明:

没有加入安全框架的SpringBoot web程序,默认所有资源均不受保护。

1.2.8 问题

我们的项目很多资源必须被保护起来,如何保护?引入安全框架

2 认证授权等基本概念

2.1 认证(authentication)

2.1.1 系统为什么要认证?

认证是为了保护系统的隐私数据与资源,用户的身份合法方可访问该系统的资源。

2.1.2 什么是认证(登录)?

认证 :用户认证就是判断一个用户的身份是否合法的过程。

2.1.3 常见的用户身份认证方式

Ø 用户名密码登录
Ø 二维码登录
Ø 手机短信登录
Ø 指纹认证
Ø 人脸识别
Ø 等等…

2.2 会话(session)

2.2.1 什么是会话

用户认证通过后,为了避免用户的每次操作都进行认证可将用户的信息保存在会话中。会话就是系统为了保持当前用户的登录状态所提供的机制,常见的有基于****session方式、基于token方式等。

2.2.2 基于session的认证方式

它的交互流程是,用户认证成功后,在服务端生成用户相关的数据保存在session(当前会话)中,发给客户端的sesssion_id 存放到 cookie 中,这样用户客户端请求时带上 session_id 就可以验证服务器端是否存在 session 数据,以此完成用户的合法校验,当用户退出系统或session过期销毁时,客户端的session_id也就无效了。

2.2.3 基于token的认证方式

它的交互流程是,用户认证成功后,服务端生成一个token发给客户端,客户端可以放到 cookie 或 localStorage等存储中,每次请求时带上 token,服务端收到token通过验证后即可确认用户身份。可以使用Redis 存储用户信息(分布式中共享****session)。
基于session的认证方式由Servlet规范定制,服务端要存储session信息需要占用内存资源,客户端需要支持cookie;基于token的方式则一般不需要服务端存储token,并且不限制客户端的存储方式。如今移动互联网时代更多类型的客户端需要接入系统,系统多是采用前后端分离的架构进行实现,所以基于****token的方式更适合

2.3 授权(authorization)

2.3.1 为什么要授权(控制资源被访问)?

因为不同的用户可以访问的资源是不一样的。

2.3.2 什么是授权(给用户颁发权限)

授权: 授权是用户认证通过后,根据用户的权限来控制用户访问资源的过程。
拥有资源的访问权限则正常访问,没有权限则拒绝访问。

2.4 RBAC(Role-Based Access Control) 基于角色的访问控制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KSusII0c-1681958373975)(https://cdn.nlark.com/yuque/0/2023/png/32441366/1681955131923-fbaab2ec-0224-43ed-bc32-7d1dcda26022.png#height=198&width=415)]
用户,角色,权限 本质:就是把权限打包给角色(角色拥有一组权限),分配给用户(用户拥有多个角色)。
最少包括五张表 (用户表、角色表、用户角色表、权限表、角色权限表)

3 java的安全框架实现

主要有三种方式:

| Ø Shiro:轻量级的安全框架,提供认证、授权、会话管理、密码管理、缓存管理等功能
Ø Spring Security:功能比Shiro强大,更复杂,权限控制细粒度更高,对OAuth2 支持更好,与Spring 框架无缝集合,使Spring Boot 集成很快捷。

Ø 自己写:基于过滤器(filter)和AOP来实现,难度大,没必要。

4 Spring Security

4.1 什么是Spring Security

Spring Security是一个能够为基于Spring的企业应用系统提供声明式(注解)的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
以上解释来源于百度百科。可以一句话来概括:

SpringSecurity 是一个安全框架

4.2 官方网址

https://spring.io/projects/spring-security

查看下官网

5 认证入门

5.1 安全入门项目

5.1.1 新建模块springsecurity-02-hello

5.1.2 添加依赖和maven插件

此处可以使用bootpom 模板创建临时文件,并拷贝。

5.1.3 添加spring-boot-starter-security依赖

|

<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>

5.1.4 新建启动类

新建启动类Application,学员自行创建

5.1.5 新建三个controller

参照1.2.4 创建,可以直接拷贝过来
小提示:能使用键盘的地方,多使用键盘,少使用鼠标

重命名快捷键(shift+F6),移动文件快捷键 F6

5.1.6 启动程序,并使用浏览器访问

http://localhost:8080/student/query

系统会跳转到登录页面

运行结果说明:

spring Security默认拦截了所有请求,但登录退出不拦截

5.1.7 登录系统

使用默认用户user登录系统,密码是随机生成的UUID字符串,可以在控制台(console)上找到。

登录系统,再次访问:

|http://localhost:8080/student/query
http://localhost:8080/teacher/query
http://localhost:8080/admin/query

发现登录后的用户均可以正常访问

5.1.8 退出系统

http://localhost:8080/logout


单击Log Out 按钮,成功退出

5.1.9 结论

| 引入spring-boot-starter-security依赖后,项目中除登录退出外所有资源都会被保护起来

认证(登录)用户可以访问所有资源,不经过认证用户任何资源也访问不了。

5.1.10 问题

所有资源均已保护,但是用户只用一个,密码是随机的,只能在开发环境使用

5.2 使用配置文件配置用户名和密码

5.2.1 新建模块springsecurity-03-configfile

模仿5.1.1 新建即可。

5.2.2 添加安全依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency> 

5.2.3 新建启动类

新建启动类Application,学员自行创建

5.2.4 新建三个controller

参照1.2.4 创建,可以直接拷贝过来

5.2.5 新建配置文件application.yml

添加spring security 配置信息

spring:security:user:name: adminpassword: 888888 

5.2.6 启动运行并使用浏览器测试

发现使用配置文件中的用户名和密码可以正常访问。
配置文件中配置用户后,默认的user用户就没有了。
示例说明:可以通过配置文件配置用户和密码,解决了使用随机生成密码的问题。

5.2.7 查看源码

问题:
Ø 查看源码的快捷键是什么?
Ø 反编译生成代码和源码的区别?
Ø 如何下载源代码?
Ø 下载后的源代码存储到哪去了?

查看源码的快捷键:ctrl+鼠标左键
application.yml 中将鼠标指定到name那,按住ctrl键,单击鼠标左键

单击上图中 Download Sources,下载源码文件

可以看到默认用户名为user,密码为使用UUID随机生成的字符串。

5.2.8 问题

Spring Security配置文件中默认配置用户是单一的用户,大部分系统都有多个用户,多个用户如何配置?

5.3 基于内存的多用户管理

5.3.1 新建模块springsecurity-04-inmemory

5.3.2 添加安全依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency> 

5.3.3 新建启动类

新建启动类Application,学员自行创建

5.3.4 新建三个controller

参照1.2.4 创建,可以直接拷贝过来

5.3.5 新建配置文件application.yml

参照5.2.5 ,可以直接拷贝内容

5.3.6 新建配置类


com.powernode.config包下新建配置类MySecurityUserConfig,如下:

@Configurationpublic class MySecurityUserConfig {@Beanpublic UserDetailsService userDetailService() {//        使用org.springframework.security.core.userdetails.User类来定义用户//定义两个用户UserDetails user1 = User._builder_().username("eric").password("123456").roles("student").build();UserDetails user2 = User._builder_().username("thomas").password("123456").roles("teacher").build();//创建两个用户InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();userDetailsManager.createUser(user1);userDetailsManager.createUser(user2);return userDetailsManager;}} 

5.3.7 启动程序测试

登录页面输入用户名(thomas)和密码(123456),然后单击登录后,控制台报错,如下:

报错的原因如下:
这个是因为spring Sercurity强制要使用密码加密,当然我们也可以不加密,但是官方要求是不管你是否加密,都必须配置一个密码编码(加密)器

5.3.8 添加密码加密器bean但是不对密码加密

在MySecurityUserConfig类中加入以下bean

 /**从 Spring5 开始,强制要求密码要加密*如果非不想加密,可以使用一个过期的 PasswordEncoder 的实例 NoOpPasswordEncoder,*但是不建议这么做,毕竟不安全。*@return*/@Beanpublic PasswordEncoder passwordEncoder(){//不对密码进行加密,使用明文return NoOpPasswordEncoder._getInstance_();} 

重启程序再次使用thomas/123456登录测试,可以登录正常访问了。
使用admin/888888登录,登录不成功,说明:我们只要添加了安全配置类,那么我们在****yml里面的配置就失效了

此处可以查看一下NoOpPasswordEncoder源码,再看一下单例模式,加密和密码对比方法
英文小提示:
明文:plaintext
密文:ciphertext
问题:
Ø 密码为什么要加密?加密的方式有哪些? 涉及到密码加密问题
Ø NoOpPasswordEncoder此类已经过期,而且还没有加密,如何解决?下章解决
Ø 以学生身份登录,发现不但可以访问学生的页面,还可以访问教师的页面和管理员的页面,如何解决? 权限问题,后面解决
Ø 如果要动态的创建用户,或者修改密码等(不是把用户名和密码写死到代码中),怎么办? 认证信息要存储到数据库中。

下面一章讲解密码加密问题


http://www.ppmy.cn/news/46190.html

相关文章

深入剖析 Qt QMultiMap :原理、应用与技巧

目录标题 引言QMultiMap 的基本用法接口的用途和实际应用场景综合示例展示QMultiMap的所有用法 迭代器&#xff1a;遍历 QMultiMap 中的元素&#xff08;Iterators: Traversing Elements in QMultiMap &#xff09;QMultiMap 的高级用法QMultiMap 的优点和局限性优点局限性 QMu…

一起读源码 —— Fastjson 的核心方法及其实现原理

源码介绍 Fastjson 是阿里巴巴开源的一个 Java 工具库&#xff0c;它常常被用来完成 Java 的对象与 JSON 格式的字符串的相互转化。 此文读的源码是撰写此文时 Fastjson 的最新的发布版本&#xff0c;即 1.2.83 下载源码 请前去 github 找到 release 最新版下载后解压&…

JUC源码系列-ReentrantLock独占锁的释放

前言 开始之前先提一句, JAVA的内置锁在退出临界区之后是会自动释放锁的, 但是ReentrantLock这样的显式锁是需要自己显式的释放的, 所以在加锁之后一定不要忘记在finally块中进行显式的锁释放: Lock lock new ReentrantLock(); ... lock.lock(); try {// 更新对象//捕获异常…

IOC容器——Bean

IOC容器——Bean Bean配置name别名属性Bean作用范围scopeBean的实例化构造方法示例化静态工厂实例化实例工厂与FactoryBean实例工厂FactoryBean bean的生命周期 Bean配置 name别名属性 Bean ID 唯一&#xff0c;而关于Spring别名&#xff0c;我们可以在配置文件中使用name来定…

《高等工程数学》各知识点解题思路梳理(基于AI模型)

《高等工程数学》各知识点解题思路梳理 **一、填空题****1.给定线性空间的一个基&#xff0c;求一给定向量在该基下的坐标****2. 给定欧氏空间的标准正交基&#xff0c;求一给定向量的长度****3.求给定矩阵的2-范数、无穷范数&#xff0c;1-范数****4.确定方阵幂级数收敛的条件…

COMSOL锂离子电池仿真技术与应用

背景&#xff1a; 随着各国燃油车禁售时间表的推出&#xff0c;新能源汽车的地位愈发稳固。而锂离子电池作为电动车的核心动力源&#xff0c;也越来越受到市场的追捧。锂离子电池在制作过程中涉及正极、电解液、负极、隔膜等材料的选取与匹配&#xff0c;极片设计参数的选择等…

Docker容器---网络、容器操作

Docker容器---网络、容器操作 一、docker实现原理二、docker网路模式1、Host模式2、container模式3、none模式4、bridge模式 三、自定义网络1、查看网络模式列表2、查看容器信息3、指定分配IP地址4、自定义网络固定IP 四、暴露端口五、容器端口映射1、创建端口映射 六、资源控制…

深度学习快速参考:11~13

原文&#xff1a;Deep Learning Quick Reference 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只关心如何实现目…