1.什么是Spring Security?

在了解Spring Security之前,我们是不是应该先思考一个问题,我们自己写的web案例一般都需要先登录,之后登录之后才能访问其他页面,或者说我们不同的用户登录之后能进行的操作不同,比如系统管理员和普通用户所能操作的功能是有所区别的。那我们如何解决这个问题?

不错,这时候我们就需要用到一些安全框架,比较Apache 旗下的Shiro、Spring家族中的Spring Security,Shiro相比Spring Security而言,比较简单易上手,不过我们这篇文章主要讲解Spring Security的简单应用。

接着上面的话题,Spring Security提供了一组可用在Spring应用上下文中配置的Bean,充分的利用了Spring IOC、DI(依赖注入)、AOP(面向切面编程)的功能,提供了生命式的安全访问控制功能,提高了开发效率。

Spring Security的本质就是一组过滤器链(16个),通过创建大量的filter和interceptor来进行请求的验证和拦截,以此来达到安全校验和鉴权的效果。

2.如何使用Spring Security?

要使用Spring Security很简单,我们只需要引入Spring Security 的相关依赖,就可以得到一个Spring Security的简单示例。

创建Spring Boot项目 ,引入相关的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--mysql依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis-plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.1.tmp</version></dependency><!--security 依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!--JWT 依赖--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency>

配置yaml文件,主要配置数据源:

server:#配置服务端口号port: 8081
spring:datasource:#配置数据库驱动driver-class-name: com.mysql.cj.jdbc.Driver  #配置数据库地址,务必加上时区url: jdbc:mysql://localhost:3306/yeb?useUnicode=true%&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai#数据库账户名称username: root#数据库密码password: XXXXX

然后启动Spring Boot项目,你会发现,咦,我明明没有编写登录页面,为什么它需要我登录?

没错,我们的Spring Security已经生效了,尽管我们什么也没做,只是引入了一个依赖而已,这是Spring Security的默认行为,只要我们添加了Spring Security的依赖,后续我们的所有操作都必须要通过它的验证才能继续。

它的账户是user,密码在我们后端控制台,每次生成的密码都是随机的,我们需要到后端控制台复制密码。

输入用户名,密码,就可以跳转到我们原来的页面。

通过这个简单的使用, 你现在是不是对Spring Security有了大概的认识了。

3.Spring Security 的进阶使用,UserDetailsService的详解。

我们当然不是只能使用它提供给我们的登录页面,我们可以通过相关的配置,将它的登录页面,替换为我们本来的的登录页面。

当我们需要自定义它的验证逻辑时,我们就需要来实现UserDetailsService这个接口

点开它我们发现它里面只有一个方法,并且这个方法的作用是通过用户名加载用户,用户名怎么来的,看见后面的参数了么,它就是前端传递过来的用户名称,而且返回一个UserDetails的一个类,那这个类又是什么呢?,我们继续点开看看。

点开这个类之后,我们发它仍然是一个接口,并且提供了很多方法,接口意味着我们要想使用它是不是就得现实现它,说明UserDetails在Spring Security中已经有了一个实现类了,接下来我们继续寻找UserDetails的实现类,并且观察它的实现类。

我们ctrl+alt 点击UserDetails,就可以看到它的实现类,我们发现它确实存在一个实现类,并且类名为User,我们要注意把这个User区分开,这是Spring Security提供的User,同样的我们点开观察它。

这个类里面的东西很多,我就不全部截图啦,大家可以自己点开看一下。总之,这个实现类User的意思大概就是根据客户端传递过来的用户名,它会去查询数据库,并且返回查到的相应信息,包括密码、用户名、权限信息、是否可用,账户是否失效等等。

我们在回到UserDetailsService这个类,我们发现它抛出了一个异常,这个异常就是没有查询到数据时,它就会抛出这个异常。

4.PasswordEncoder详解。

要实现Spring Security的自定义验证流程,我们除了实现USerDetailsService这个接口,我们还需要实现PasswordEncoder。当我们没有进行任何配置的时候,Spring Security它已经自带了一个实现了PasswordEncoder的实例,这就是我们刚刚运行时,控制台打印密码是那么一长串字符的原因。

PasswordEncoder接口包含三个方法,如下:

PasswordEncoder的实现类很多,每一个实现类都代表一种加密算法,官方推荐我们使用BCryptPasswordEncoder这种算法。

大家也可以ctrl+alt点开看一看里面的内容,

这里我们可以通过一个测试类来测试它的加密效果:

//创建BCryptPasswordEncoder对象PasswordEncoder pe=new BCryptPasswordEncoder();String encode = pe.encode("123456");//调用encode方法加密,得到加密后的字符串System.out.println("加密后的密码 = " + encode);boolean matches = pe.matches("123456", encode);//调用matches方法匹配原密码和加密之后的密码System.out.println("原密码与加密后的密码是否相等 = " + matches);

运行结果如上,通过这个小例子是不是对PasswordEncoder接口的使用有了更加深入的了解。

5.自定义登录登录逻辑

了解了UserDetailsService和PasswordEncode之后,我们是不是就能自定义登录逻辑了,

现在我们回顾一下,给大家三分钟回想一下UserDetailsService是干啥的,有哪些方法,通过它我们可以干些啥,PasswordEncoder的方法及作用,可以用在什么场景,大家想一想,思考一下。

在实现我们的自定义登录逻辑之前,我们的Spring Securit要求我们进行自定义登录逻辑时,我们的容器中必须有一个PasswordEncoder的实例存在,所以我们不能想上面那个例子一样直接用new的方式,我们需要写一个配置类,将它注入到容器当中。

代码如下:

@Configuration
public class SecurityConfig {@Beanpublic PasswordEncoder getpw(){return new BCryptPasswordEncoder();}
}

接下来创建一个类去实现UserDetailsService接口,重写UserDetails方法,我们在serve层创建一个类UserDetailsServiceImpl去实现UserDetailsService接口,并且重写UserDetails方法。如图。

OK,现在想一想我们应该做什么,它只有这个方法,这个方法有什么用。

具体如下:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate PasswordEncoder pe;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//1.查询数据库判断用户名是否存在,如果不存在则抛出异常UsernameNotFoundException//怎么查数据库?这应该都会吧,我这里就不弄查数据库的部分了,节省时间,写几个小时了,这里我们就自己造一个数据吧,//假设我们从数据中查到的用户名为YangJunDong,我们直接判断就是if(!"YangJunDong".equals(username)) { //注意这个username是传递过来的参数,也就是前端输入框中的名字throw new UsernameNotFoundException("用户名不存在!");}//2.将查询出来的密码(数据库中已加密的密码)进行解析,或者直接放到实现类的构造函数中?/*这里咱也不查数据库了,自己造一个密码吧,但是这个密码是数据库中的,我们得造一个加密的密码之前写的配置类管用了吧,我们直接Resource注入进来就好了*/String password = pe.encode("123");//通过数据库查到密码之后怎么做?我们这里采用直接放到到实现类(UserDetailsService的最终实现类是啥来着)的构造函数中,代码如下return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList( "admin" ));//这里的三个参数,前两个用户名密码,不必多说,但是第三个是权限信息,同样的我们没查数据库,也只能造一个,使用AuthorityUtils工具类中//的commaSeparatedStringToAuthorityList方法,给其设置权限,我设置的权限是admin的权限,当然也可以短号隔开设置多个权限,一个人也存有多种权限的情况的}
}

OK,到这里我们就成功自定义了登录逻辑,现在在次运行项目,然后我们会发现,控制台居然没有打印密码了,说明我们已经更改掉了它的默认方式,输入我们从数据库(自定义)的账号和密码。

登录成功!!!

那如果我们输出错误的密码,或者错误的用户名呢?

OK,可以看到输入错误的信息是无法通过验证的。

以上就是这篇文章的内容了,这篇文章主要说了Spring Security的作用,以及UserDetailsService和PasswordEncoder接口的作用和使用方法,并且通过这个两个接口自定义了登录逻辑,也就是让它去查数据库,实打实的来,而不是用它默认的方法生成账户和密码,如果有错误的地方请大家指正。

后续会陆续更新自定义登录页面(将登录页面换成我们自己的登录页面)和Spring Security的其他功能。

Spring Security是什么,以及如何在Spring Boot项目中整合Spring Security并且使用它,下面我们通过一个登录案例简单介绍一下Spring Security。相关推荐

  1. Spring Boot项目中使用RestTemplate调用https接口出现 unable to find valid certification path to requested target

    问题描述:Spring Boot项目中使用RestTemplate调用https接口出现以下错误: PKIX path building failed: sun.security.provider.c ...

  2. Spring Boot项目中集成Elasticsearch,并实现高效的搜索功能

    Spring Boot项目中集成Elasticsearch 前言 环境准备 引入依赖 配置Elasticsearch连接信息 定义实体类 定义Elasticsearch操作接口 实现搜索功能 总结 前 ...

  3. spring boot 项目源码_Spring Boot2 系列教程(三)理解 Spring Boot 项目中的 parent

    前面和大伙聊了 Spring Boot 项目的三种创建方式,这三种创建方式,无论是哪一种,创建成功后,pom.xml 坐标文件中都有如下一段引用: <parent><groupId& ...

  4. 在Spring Boot项目中使用Spock框架

    转载:https://www.jianshu.com/p/f1e354d382cd Spock框架是基于Groovy语言的测试框架,Groovy与Java具备良好的互操作性,因此可以在Spring B ...

  5. scheduled每天下午1点执行一次_在Spring Boot项目中使用@Scheduled注解实现定时任务...

    在java开发中定时任务的实现有多种方式,jdk有自己的定时任务实现方式,很多框架也有定时任务的实现方式.这里,我介绍一种很简单的实现方式,在Spring Boot项目中使用两个注解即可实现. 在sp ...

  6. Spring Boot 项目中Java对象的字符串类型属性值转换为JSON对象的布尔类型键值的解决方法及过程

    文章目录 场景描述 示例说明 解决历程 @JsonFormat是否能解决问题? 万能方案-调试 替代方案 补充知识 Java对象与JSON对象的序列化与反序列化 相关注解说明 后记 场景描述 在Spr ...

  7. 如何在 GitHub 的项目中创建一个分支呢?

    https://www.cnblogs.com/plBlog/p/11573234.html https://www.cnblogs.com/wulibo/p/10608471.html https: ...

  8. 简单介绍基于Spring Boot的项目骨架使用

    前言 从大学开始接触 java 后台开发,到后来了解了更多的编程语言的开发.发现 java 的开发可以说是相较而言很复杂的了,光是 Spring MVC 的配置要是没有经历系统的学习,可能就能劝退一波 ...

  9. 在Spring Boot 项目中使用Spring AOP实现切面日志

    导语   大数据时代,数据来源是比较重要的.而日志作为用户操作.系统监控.业务分析等都比较重要的一个环节.能更好的使用日志显得尤为重要.那么在Spring Boot的项目中如何能更加高效的记录Cont ...

最新文章

  1. Angular-搜索框及价格上下限
  2. 架构师之路 — 分布式系统 — gRPC 谷歌远程过程调用
  3. Scala基础 - 下划线使用指南
  4. python中一个范围怎么表示_我应该如何处理Python中的包含范围?
  5. 第六章 定积分的应用 —— 第一节 定积分的元素法
  6. 从边缘到云,万物互联时代Aruba的技术经
  7. 防止头文件重复包含之pragma once与#ifndef
  8. GolVe向量化做文本分类
  9. vb 6.0 常用工具(鼠标移动,代码补全,代码对齐)
  10. Neo4j 下载安装
  11. 刻录软件nero序列号有效性的检测
  12. python 区块链开发教程_区块链开发教程分享【201904】
  13. 飞信机器人FXRobot
  14. 一:以理论结合实践方式梳理前端 ES 6+ ——— ES 6+ 能干什么
  15. Matplotlib直方图
  16. Hitting Set 碰撞集问题
  17. 最小公倍数用c语言,如何用C语言求最小公倍数。。。
  18. 计算机基础知识试题答案6,计算机基础知识试题及答案
  19. Tensorflow变量作用域及变量初始化
  20. 一加7t人脸识别_90Hz新品,一加7T系列国内发布日期官宣

热门文章

  1. linux下weblogic12c漏洞修复打补丁基本操作
  2. html picker插件,jQuery元素选择器插件-multiPicker
  3. C++_OpenCV录制视频
  4. 斜杠青年Ruff:区块链只是分内事 1
  5. HP OV NNM dynamic view error
  6. P1536 村村通 洛谷
  7. matlab直接读取Kinect V2的两种方式(实现骨骼识别、kinect studio对接)
  8. Nacos配置文件误删恢复
  9. 物联网(IoT)技术领域-lora技术简介及相关技术间的对比分析
  10. 一个自媒体人的日常!