SpringBoot2.3集成Spring Security(一)

news2024/11/29 4:51:42

业务背景

首先一个项目最基础的部分一定是登录部分,那么有了登录肯定会有对应的权限校验、身份校验。
那么在没有使用Spring Security之前,大多数设计思路都是通过各种拦截器、监听器来控制用户的访问。但是这种方式,后续的维护会越来越复杂,如果要增加或者修改一个逻辑,其中拦截器、监听器的改动会很多。
因此,在这种情况下,我们使用spring Security帮助我们进行身份认证、访问授权等功能。

Spring Security简介

附上一段官网的解释:

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements

翻译:Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。 它是保护基于 Spring 的应用程序的事实标准
Spring Security 是一个专注于为 Java 应用程序提供身份验证和授权的框架。 像所有 Spring 项目一样,Spring Security 的真正强大之处在于它可以轻松扩展以满足自定义需求

SpringBoot集成Spring Security

1. 添加maven包

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

2. 启动项目

启动成功
访问地址:http://localhost:8888/login
访问页面
输入用户名:user
输入密码:控制台打印
即可登录成功。

就这么简单?

以上方式,可以看出来:Spring Security 对于集成还是很友好的。只需要添加maven文件就可以了。
但问题是:谁会用这种方式?每次启动都使用随机密码?一个很破的登录页面?
因此,从这里开始,才是本文真正开始介绍Spring Security。

从哪儿开始?Spring Security 三种认证方式

有点蒙,这下一步应该从哪儿开始?稍微网上翻一翻我们就能知道,Spring Security提供了三种认证方式。既然我们暂时没有思路的话,就先从这三种认证方式下手吧。

1. 默认身份认证:就是我们启动项目之后,控制台打印的密码。默认用户名:user

2. 内存身份认证:

直接上代码:

/**
 * Spring Security 配置类
 *
 * @author caojing
 * @since 2023/6/14
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().successForwardUrl("/test");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        auth.inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("user").password(encoder.encode("123456")).roles("USER");
    }
}

注意点:这里一定要设置加密方式,不然会报错:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

3. 自定义实现类

自定义一个类MyUserDetailService实现UserDetailService接口:代码如下所示:

/**
 * 自定义认证方式
 *
 * @author caojing
 * @since 2023/6/14
 */
@Service
public class MyUserDetailService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //todo 这里可以从数据库获取对应的用户信息

        // 权限信息设置
        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
        // 设置用户名密码和权限信息
        return new UserBean("caojing", new BCryptPasswordEncoder().encode("123"), auths);

    }
}

SecurityConfig类

/**
 * Spring Security 配置类
 *
 * @author caojing
 * @since 2023/6/14
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailService userDetailService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().successForwardUrl("/test");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
//        auth.inMemoryAuthentication()
//                .passwordEncoder(new BCryptPasswordEncoder())
//                .withUser("user").password(encoder.encode("123456")).roles("USER");
        auth.userDetailsService(userDetailService).passwordEncoder(new BCryptPasswordEncoder());
    }
}

UserBean实体类:

/**
 * @author CAOJING
 * @date 2023/4/26
 * @description
 */
@Data
public class UserBean implements UserDetails {
    private int id;
    private String name;
    private int age;
    private String password;
    private Date createTime;
    Collection<? extends GrantedAuthority> authorities;

    public UserBean(String name, String password, List<GrantedAuthority> auths) {
        this.name = name;
        this.password = password;
        this.authorities = auths;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return new ArrayList<>();
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return name;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

启动项目,访问地址:http://localhost:8888/login,输入帐号名:caojing。密码:123。成功
在这里插入图片描述

思路分析:

咱们从结果来看。不管是内存模式还是自定义模式,我们是不是都是在一个继承了WebSecurityConfigurerAdapter的配置类中,有个方法:configure(AuthenticationManagerBuilder auth)进行配置的?
那么,我们可以稍微分析一下这个方法:
先看参数:AuthenticationManagerBuilder

/**
 * {@link SecurityBuilder} used to create an {@link AuthenticationManager}. Allows for
 * easily building in memory authentication, LDAP authentication, JDBC based
 * authentication, adding {@link UserDetailsService}, and adding
 * {@link AuthenticationProvider}'s.
 *
 * @author Rob Winch
 * @since 3.2
 */
 public class AuthenticationManagerBuilder extends
		AbstractConfiguredSecurityBuilder<AuthenticationManager, AuthenticationManagerBuilder>
		implements ProviderManagerBuilder<AuthenticationManagerBuilder> {

很明显,这个验证了我们刚才设置方式的做法:内存模式、LDAP模式、JDBC模式(注意这个模式是配置数据库连接,跟我们实际想要的效果还是不太一样)。
不管是我们刚才配置的内存模式、自定义模式都是通过AuthenticationManagerBuilder这个类进行配置.

疑问:为什么要实现 UserDetailService接口?

或者说:为什么实现了这个接口,spring Security 验证的时候,就能走我实现的类?
一步一步往下走,看源码。从SecurityConfiguserDetailsService方法进去
在这里插入图片描述
注意到这里是new了一个 DaoAuthenticationConfigurer类,并且初始化的时候,把我们自己的useDetailService作为构造参数传入
继续查看DaoAuthenticationConfigurer
在这里插入图片描述
想不到啊。这还是个父类,继续往下:
在这里插入图片描述
这里又将我们自定义的类赋值到DaoAuthenticationProvider类中。
到这里停一停:其实源码翻到这儿差不多就知道为什么要实现UserDetailsService类了。不知道大家注意到了没?我们看到的几个set方法,参数都是接口类UserDetailsService。因此,我们在配置类中设置的自定义类如果不实现UserDetailsService,编译的时候都会报错,所以肯定是要实现这个接口。
但是,到这里。还不能完全解决我的疑问:现在是解决了为什么这样?但是还没解决为什么这样就可以
go on
查看DaoAuthenticationProvider
这个类代码不多,一共200行不到。我们可以看下UserDetailsService在哪边使用到了
在这里插入图片描述
!!!终于找到了,在DaoAuthenticationProvider108行调用了我们自定义的类。

思路总结:

  1. 先实现想要的效果:从结果开始导向。
  2. 从源码中分析:有子类先看子类,子类中不存在查看对应的父类。
  3. 反向:AuthenticationManagerBuilder -> AbstractDaoAuthenticationConfigurer -> DaoAuthenticationProvider->retrieveUser方法108行

下一步

这篇文章已经初步集成了Spring Security ,并且用户的来源是数据库。但是这样的一个集成效果其实还是没有达到我们真正使用的标准,以下是我觉得还能进一步集成的点。
现在大多数项目都是前后端分离的项目,因此传统的seesion方式前后端绑定太严格,我们不予采用,因此需要一种更为简便、快捷的方式。也就是JWT。
下一篇文章,会给大家介绍如何在spring Security中集成 JWT。

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

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

相关文章

组合模式(十二)

请相信自己&#xff0c;请再次相信自己&#xff0c;请一定要相信自己 上一章简单介绍了装饰者模式(十一), 如果没有看过, 请观看上一章 一. 组合模式 引用 菜鸟教程里面的 组合 模式介绍: https://www.runoob.com/design-pattern/composite-pattern.html 组合模式&#xff0…

有多少运维配置防火墙忽略了长连接?

长连接的使用场景 当业务中客户端和服务器长时间无数据交互&#xff0c;空闲时间超过1800秒&#xff0c;会话会因超时被清除。后续客户端没有重新发起连接&#xff0c;直接发送控制报文时导致数据不通。常见于数据库连接。 1. 重点说明 以天为单位的会话超时需要开启长效会话比…

Android 进程间通信机制(六) 手写AIDL文件

阅读本篇文章前, 请先查看一下笔者之前的写的两篇博客文章: Android Service知识 和 Android AIDL使用 进程间通信涉及到客户端和服务端, 肯定有绑定服务的过程, 所以要阅读一下Android Service相关的知识, 跨进程通信的媒介aidl文件,我们也必须要了解怎么创建的,有什么规则…

【Jenkins】全网最详细的自动化测试

学习 Jenkins 自动化测试的系列文章 Robot Framework 概念Robot Framework 安装Pycharm Robot Framework 环境搭建Robot Framework 介绍Jenkins 自动化测试 1. Robot Framework 概念 Robot Framework是一个基于Python的&#xff0c;可扩展的关键字驱动的自动化测试框架。 它…

走进人工智能|GANs AI时代下的前卫艺术

前言&#xff1a; GANs的作用是以生成模型的形式学习数据分布&#xff0c;从而产生逼真的样本数据&#xff0c;可以应用于图像合成、风格转换、视频生成等领域。 文章目录 序言背景适用领域技术支持应用领域程序员如何学总结 序言 GANs&#xff08;生成对抗网络&#xff09;是…

测试为什么分白盒、黑盒、单元、集成测试?

一、为什么测试的概念这么多 一个软件项目就好比一部复杂的汽车&#xff0c;有很多零件&#xff0c;当每个零件生产完成后&#xff0c;就要测试零件是否存在质量问题。零件组成复杂的汽车后&#xff0c;我们还要测试汽车。比如著名的中保研&#xff0c;测试刹车&#xff0c;测…

运维圣经:挖矿木马应急响应指南

目录 挖矿木马简介 挖矿流程 挖矿木马应急响应 一. 隔离被感染主机 二. 确定挖矿进程 三. 挖矿木马清除 1、阻断矿池地址的连接 2、清除挖矿定时任务、启动项等 3、禁用可疑用户 4、定位挖矿木马文件的位置并删除 5、全盘杀毒、加固 挖矿木马简介 挖矿&#xff1a;…

喜报|瑞云科技荣获“年度汽车数字化营销供应商”奖

由iDigital China举办&#xff0c;中国国际贸易促进委员会汽车行业分会战略支持的ADMIC汽车数字化&营销创新峰会暨金璨奖颁奖盛典于2023年4月19日在上海圆满落幕。深圳市瑞云科技股份有限公司受邀参会&#xff0c;现场设有展位&#xff0c;为观众展示实时云渲染如何助力汽车…

实现阿里云域名的DDNS

实现阿里云域名的DDNS 目前现状与痛点 我们在使用ddns的时候会不会遇到这样的问题&#xff1a;路由器只支持指定的域名服务提供商或者是指定的域名&#xff0c;比如我的华为路由器就只支持花生壳&#xff1a; 我想看到这篇文章的小伙伴们应该都把域名注册到中国最大的域名注…

Nginx安装与配置

Nginx安装与配置 一、简介二、安装三、功能与配置3.1、正向代理3.2、反向代理3.3、负责均衡3.4、ip_hash3.5、轮询3.6、加权轮询 四、nginx安全相关配置五、常用命令 一、简介 Nginx是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。 Ngin…

Windows11 安装 CUDA/cuDNN+Pytorch

一、准备工作&#xff1a; 查看torch版本&#xff1a;进入python交互环境&#xff1a; >>>import torch >>>torch.__version__ 查看cuda版本&#xff1a;CMD窗口 nvcc --version 如果版本不一致&#xff0c;需要卸载再重装。 二、安装 Windows 安装 CU…

【裸机开发】指定外设根时钟配置实验(三)—— 寄存器分析篇(PERCLK_CLK_ROOT、IPG_CLK_ROOT)

前面已经完成了 PLL1 和 8 路 PFD 的初始化&#xff0c;至于其他 PLL 路&#xff0c;等实际需要的时候再初始化也不迟。接下来我们就挑选几个具体的外设时钟进行配置。 假设我们要初始化下面两个根时钟PERCLK_CLK_ROOT、IPG_CLK_ROOT。&#xff08;中途可能还涉及到根时钟 AHB…

【01】如何在电脑上使用wink一键高清短视频

如何在电脑上使用wink一键高清优化短视频画质 文章目录 如何在电脑上使用wink一键高清优化短视频画质1.软件简介1.1痛点1.2解决方案 2.实际操作2.1准备工作2.1.1下载雷电模拟器2.1.2下载wink 2.2.安装软件2.2.1安装雷电模拟器2.2.2安装wink2.2.2.1在雷电模拟器中安装wink2.2.2.…

【操作系统】计算机操作系统知识点总结

文章目录 前言一、操作系统的概念与发展二、操作系统的结构与功能1、操作系统的结构2、操作系统的功能 三、进程管理1、进程2、进程的创建3、进程管理的实现4、进程控制块 四、内存管理1、内存2、内存管理3、内存管理的实现 五、文件系统1、文件系统2、文件系统的主要任务3、文…

微服务springcloud 03.Eureka实现高可用

01.运行时候项目图存在两个item service&#xff0c;和两个Eureka注册中心 02.在已有的项目中扩展service服务数量&#xff08;item service的数量变成两个&#xff09; 第一步&#xff1a;配置item service的启动参数 启动参数的优先级要高于yml文件的优先级 具体参数是&#…

两万字深入浅出yolov5+deepsort实现目标跟踪,含完整代码, yolov,卡尔曼滤波估计,ReID目标重识别,匈牙利匹配KM算法匹配

目录 一&#xff1a;前言 二&#xff1a;跟踪部分&#xff1a; ReID结构​编辑 第一帧&#xff08;生成track&#xff09; 第二帧 更新先验的预测值 状态矩阵的初始化 对预测值进行更新&#xff08;矫正&#xff09;&#xff1a; 匹配完成&#xff0c;进行矫正的更新&…

CSC改派+延期|影像学医生赴英国伦敦国王学院从事访学研究

因美国拒签&#xff0c;又临近派出截止期限。为避免出国指标作废&#xff0c;Q医生希望获得英国高校的邀请函&#xff0c;以申请CSC的改派并延期。我们为其落实了世界名校-英国伦敦国王学院访问学者职位&#xff0c;导师的研究方向属前沿热点&#xff0c;具有广阔的发展前景。Q…

C++【二叉树进阶试题】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C/C相关题解 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 606. 根据二叉树创建字符串102. 二叉树的层序遍历107. 二叉树的层序遍历 II236. 二叉树的最近公共祖先JZ36 二叉搜…

位姿估计 | 从目标特征点检测到目标体坐标系相对于相机坐标系的位姿估计过程

目录 引言技术流程1. PNP介绍2. ICP介绍a. 利用ICP求解目标相对相机的位姿b. 利用ICP求解相机帧间运动 引言 本文接着分享空间目标位姿跟踪和滤波算法中用到的一些常用内容&#xff0c;希望为后来者减少一些基础性内容的工作时间。以往分享总结见文章&#xff1a;位姿跟踪 | 相…

当你全力以赴世界也会为你让路,23级人大女王金融硕士准备中

当你全力以赴&#xff0c;世界也会为你让路&#xff0c;在申报人民大学与加拿大女王大学金融硕士&#xff08;国际班&#xff09;项目的路上你真的努力了吗&#xff1f; 记得曾经在知乎上看过一个问题“什么事情给你的生活带来什么改变”&#xff0c;下边有很多人回答说&#x…