Spring Security实现用户认证一:简单示例

news2025/1/22 22:57:32

Spring Security实现用户认证一:简单示例

  • 1 原理
    • 1.1 用户认证怎么进行和保存的?
      • 认证流程
      • SecurityContext保存
  • 2 创建简单的登录认证示例
    • 2.1 pom.xml依赖添加
    • 2.2 application.yaml配置
    • 2.3 创建WebSecurityConfig配置类
    • 2.4 测试

1 原理

Spring Security是一个Java框架,用于保护应用程序的安全性。它提供了一套全面的安全解决方案,包括身份验证、授权、防止攻击等功能。Spring Security基于过滤器链的概念,可以轻松地集成到任何基于Spring的应用程序中。它支持多种身份验证选项和授权策略,开发人员可以根据需要选择适合的方式。

在这里插入图片描述

从官方给的流程图可以看出,DelegatingFilterProxy通常被配置为一个Servlet过滤器,注册到Servlet容器中,而DelegatingFilterProxy会将过滤请求代理给FilterChainProxy

Spring Security中定义的过滤器链会被注册进入FilterChainProxyFilterChainProxy持有一个或多个SecurityFilterChain实例,每个实例包含一组过滤器和一个匹配规则(通常是一个请求模式)。

  • 当一个HTTP请求到达应用时,Servlet容器会首先调用DelegatingFilterProxy
  • DelegatingFilterProxy会将请求委托给FilterChainProxy
  • FilterChainProxy根据请求URL选择适当的过滤器链(SecurityFilterChain),并按顺序执行链中的过滤器。

1.1 用户认证怎么进行和保存的?

认证流程

在这里插入图片描述
从上面得知,Spring Security内部是由一个个过滤器组成的,那必然会经历一个认证过滤器。

  1. 负责认证的过滤器为AbstractAuthenticationProcessingFilter,其本质是一个抽象类型的过滤器,通过调用里面一个用于执行认证的抽象方法attemptAuthentication。那必然需要一个该抽象类的具体继承类去实现抽象方法attemptAuthentication,完成认证的功能。

  2. Spring Security中为其写了一个默认的继承类为UsernamePasswordAuthenticationFilter,实现了attemptAuthentication方法,将提交的usernamepassword生成UsernamePasswordAuthenticationToken

  3. UsernamePasswordAuthenticationFilter只是负责过滤采用用户名和密码认证方式的请求,生成的UsernamePasswordAuthenticationToken并没完成认证,而是用于后面选择合适的AuthenticationProvider

  4. ProviderManager类实现了AuthenticationManager接口,ProviderManager类管理一个List<AuthenticationProvider> providers,这里面存着可用的AuthenticationProviderProviderManager类通过UsernamePasswordAuthenticationToken选择合适的AuthenticationProvider进行具体的校验,如DaoAuthenticationProvider

如果认证失败:

  • SecurityContextHolder 被清空。
  • RememberMeServices.loginFail被调用(需要配置)。
  • AuthenticationFailureHandler 被调用。

认证成功:

  • SessionAuthenticationStrategy 被通知有新的登录。
  • Authentication 是在 SecurityContextHolder 上设置的。
  • RememberMeServices.loginSuccess 被调用。
  • ApplicationEventPublisher 发布一个 InteractiveAuthenticationSuccessEvent 事件。
  • AuthenticationSuccessHandler 被调用。

SecurityContext保存

在这里插入图片描述
在得到用户认证成功的UsernamePasswordAuthenticationToken,这个token包含了用户的用户名、权限和是否认证等信息,并且会写入到SecurityContext中。 默认情况下是保存在session中的,方便下次直接从session中获取(持久化)。

如上图所示,SecurityContext包含了AuthenticationAuthenticationUsernamePasswordAuthenticationTokenSecurityContext被设置在SecurityContextHolder中。
在这里插入图片描述
SecurityContextHolder用于存储和检索 SecurityContext。它是整个 Spring Security 框架中访问认证信息的核心组件。

由于在进入SecurityFilterChain后,肯定需要将 从Repository 获取已经认证的信息 放在 认证之前执行,才能实现一个持久化存储。否则每次都是从新认证。

判断用户是否认证的便是SecurityContextSecurityContextPersistenceFilter SecurityContextRepository 加载 SecurityContext 并将其设置在 SecurityContextHolder 上。没有获取到SecurityContext则未认证。

Spring Security中SecurityContextRepository的默认实现是HttpSessionSecurityContextRepository,所以为什么会将session作为默认的上下文存储地点。这样做的坏处是需要维持大量的session,加重了服务器的负担。

2 创建简单的登录认证示例

创建一个Spring Boot 的项目。

2.1 pom.xml依赖添加


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

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

2.2 application.yaml配置

spring:
  application:
    name: spring-security

server:
  port: 4555


logging:
  level:
    web: debug

2.3 创建WebSecurityConfig配置类

package com.song.cloud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity  //开启SpringSecurity自动配置(springboot中可以省略)
public class WebSecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests(authorize ->
                        authorize
                                .anyRequest()  //对任何请求执行认证
                                .authenticated()
                )
                // formLogin 的配置先于 httpBasic
                .formLogin(withDefaults())  //内置的表单认证 
                .httpBasic(withDefaults());  //内置的基础认证

        return http.build();
    }
}

2.4 测试

这一步便是最基本的认证配置,网页打开localhost:4555,将会自动跳转到登录页面进行认证。
在这里插入图片描述
默认的用户名为:user
默认的密码在控制台打印输出,如下。
在这里插入图片描述
登录成功的页面:
在这里插入图片描述

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

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

相关文章

全栈式数据统计:Flask+Pandas按年,季度,月统计显示

话不多说,有图有源码 1.实现效果: 按季度统计 按月度统计: 2.实现源码: 2.1)test_pandashtml.py from flask import Flask, render_template import pandas as pdapp Flask(__name__)# 自定义千分位格式化函数 def format_thousands(x):return f{x:,.2f}app.route(/) def …

JVS物联网模拟点位:如何配置并自动生成点位数据全教程

模拟点位 功能描述 模拟点位常用于业务的调试或数据展示&#xff0c;通过配置对应点位实现自动生成点位数据的功能。 界面操作 如下图所示&#xff0c;从模拟点位菜单进入模拟点位管理界面 模拟点位新增 点击新增按钮&#xff0c;如下图所示&#xff1a; ①&#xff1a;用户…

一键解锁!贸易行业实现银行与财务系统秒级对接,效率飙升!

客户介绍 某贸易有限公司是一家实力雄厚的工贸一体跨国集团企业。作为行业内的佼佼者&#xff0c;该公司以出口家纺产品和生产销售建材洁具为核心业务。公司始终坚持以市场为导向&#xff0c;不断创新和优化产品和服务&#xff0c;以满足不断变化的市场需求。 客户痛点 以往&…

猛兽派对是什么游戏 猛兽派对攻略大全 苹果电脑怎么玩《猛兽派对》?

猛兽派对是多人派对类型的游戏&#xff0c;该款游戏的动作基于物理原理设计的&#xff0c;体验游戏玩家可以选择自己喜欢的小动物角色参加派对&#xff0c;游戏内具有很多不同的关卡可供挑战。 在steam平台上&#xff0c;猛兽派对对应英文名称是PartyAnimals&#xff0c;官方正…

服务器数据恢复—服务器重装系统导致分区丢失的数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器MD1200磁盘柜通过RAID卡创建了一组RAID5阵列并分配一个LUN。在Linux系统层面将该LUN划分了sdc1和sdc2两个分区。通过LVM扩容的方式将sdc1分区加入到了卷组中的一个逻辑卷中&#xff0c;sdc2分区格式化为XFS文件系统使用。Linux操作系…

Qt编译和使用freetype矢量字库方法

在之前讲过QT中利用freetype提取字库生成图片的方法&#xff1a; #QT利用freetype提取字库图片_qt freetype-CSDN博客文章浏览阅读1.2k次。这是某个项目中要用到的片段&#xff0c;结合上一篇文章#QT从字体名获取字库文件路径使用// 保存位图int SaveBitmapToFile(HBITMAP hBi…

一行代码实现vip标志的显示

需求说明 在项目中&#xff0c;后期添加了一种用户类型。需要再用户头像右下角显示一个vip的标志。问题是只要有头像的地方都要显示。而有头像的地方很多&#xff0c;设置到的接口也很多。后面考虑通过一个工具类&#xff0c;将这个功能外挂到原来的业务需要的地方。 实现效果…

二进制部署Kubernetes集群——单Master和Node组件

前言 本文将介绍如何使用二进制文件手动搭建 Kubernetes v1.20 集群。通过这种方法&#xff0c;我们可以更好地理解 Kubernetes 的内部工作原理&#xff0c;并具备更大的灵活性和控制权。下面将逐步构建 Kubernetes 集群&#xff0c;并进一步了解其各个组件之间的交互和配置。…

【python量化交易】—— 双均线择时策略 - Qteasy自定义交易策略【附源码】

使用qteasy自定义并回测双均线交易策略 使用qteasy自定义并回测一个双均线择时策略策略思想导入qteasy模块创建一个新的策略回测交易策略&#xff0c;查看结果 使用qteasy自定义并回测一个双均线择时策略 我们今天使用qteasy来回测一个双均线择时交易策略&#xff0c;qteasy是…

kettle从入门到精通 第六十一课 ETL之kettle 任务调度器,轻松使用xxl-job调用kettle中的job和trans

想真正学习或者提升自己的ETL领域知识的朋友欢迎进群&#xff0c;一起学习&#xff0c;共同进步。若二维码失效&#xff0c;公众号后台加我微信入群&#xff0c;备注kettle。 1、大家都知道kettle设计的job流程文件有个缺点&#xff1a;只能设置简单的定时任务&#xff0c;无法…

React 第三十七章 Scheduler 最小堆算法

在 Scheduler 中&#xff0c;使用最小堆的数据结构在对任务进行排序。 // 两个任务队列 var taskQueue: Array<Task> []; var timerQueue: Array<Task> [];push(timerQueue, newTask); // 像数组中推入一个任务 pop(timerQueue); // 从数组中弹出一个任务 time…

HNU-算法设计与分析-作业3

第三次作业【动态规划】 文章目录 第三次作业【动态规划】<1>算法实现题 3-1 独立任务最优解问题<2>算法实现题 3-4 数字三角形问题<3>算法实现题 3-8 最小m段和问题<4>算法实现题 3-25 m处理器问题 <1>算法实现题 3-1 独立任务最优解问题 ▲问…

Windows 安装mysql 和 Redis

mysql Windows 图形界面安装&#xff1a; 下载mysql https://dev.mysql.com/downloads/ 1.下载完成后,找到文件双击安装程序 2. 等待一段时间&#xff0c; 选择默认&#xff0c;点击next 3. 选择安装目录 下载mysql产品 安装mysql产品 产品配置向导 安装…

数据库-索引结构(B-Tree,B+Tree,Hash,二叉树)

文章目录 索引结构有哪些&#xff1f;二叉树详解&#xff1f;B-Tree详解?BTree详解&#xff1f;Hash详解&#xff1f;本篇小结 更多相关内容可查看 索引结构有哪些&#xff1f; MySQL的索引是在存储引擎层实现的&#xff0c;不同的存储引擎有不同的索引结构&#xff0c;主要包…

Echart-折线图根据区间设置折线的样式

根据X轴区间设置折线样式 完整配置如下&#xff1a; option {xAxis: {type: category,data: [Mon, Tue, Wed, Thu, Fri, Sat, Sun]},yAxis: {type: value},series: [{data: [150, 230, 224, 218, 135, 147, 260],type: line}],//【注】&#xff1a;如果一个图中有多个折线&a…

ROS从入门到精通4-3:制作Docker镜像文件Dockerfile

目录 0 专栏介绍1 为什么需要Dockerfile&#xff1f;2 Dockerfile书写原则3 Dockerfile常用指令3.1 FROM3.2 MAINTAINER3.3 RUN3.4 ADD3.5 COPY3.6 CMD3.7 ENV3.8 EXPOSE3.9 WORKDIR3.10 ARG 4 Dockerfile构建ROS工程实例 0 专栏介绍 本专栏旨在通过对ROS的系统学习&#xff0…

springboot3.2.5+mybatis-plus导致启动报错

公司新的项目升级到了springboot3.x后&#xff0c;步步是坑&#xff0c;坑坑不同&#xff0c;各种疑难杂症层出不穷&#xff0c;让老中医也也苦不堪言&#xff0c;java的生态圈真让人无语&#xff0c;你们升级能不能认真些互相兼顾一下&#xff1f; 这次的项目用了springboot3…

Python自学之路--004:Python使用注意点(原始字符串‘r’\字符转换\‘wb’与‘w区别’\‘\‘与‘\\’区别)

目录 1、原始字符串‘r’ 2、字符转换问题 3、open与write函数’wb’与’w’区分 4、Python里面\与\\的区别 1、原始字符串‘r’ 以前的脚本通过Python2.7写的&#xff0c;通过Python3.12去编译发现不通用了&#xff0c;其实也是从一个初学者的角度去看待这些问题。 其中的\…

春风拂面,深入浅出:Bean 处理器揭秘 Spring Boot 启动之谜

春风拂面&#xff0c;深入浅出&#xff1a;Bean 处理器揭秘 Spring Boot 启动之谜 在 Spring Boot 开发中&#xff0c;Bean 处理器扮演着至关重要的角色&#xff0c;犹如幕后英雄般默默地为应用启动过程添砖加瓦。然而&#xff0c;对于许多开发者来说&#xff0c;Bean 处理器依…