spring-security 项目实战(一)个人健康档案

spring-security 项目实战(一)个人健康档案

  • 项目说明
    • 项目地址
    • 框架信息
  • 代码分析
    • 配置类解析
    • 默认登录页登录接口执行逻辑
    • 登录认证成功之后重定向到main页面过程
      • 未登录之前访问 /main
      • 生成默认登录页
      • 点击登录
    • 登录之后访问 /main
      • 执行流程
      • 清空认证信息

项目来源于《Spring Security原理与实战》,这本书对spring security介绍比较详细的,很多原理性的内容讲解的比较清晰。

项目说明

项目地址

https://gitee.com/3281328128/spring-security-basic
master 分支的代码原来书里面的代码,boot_3.2.2 分支是修改之后的代码。项目来源于书籍的第5章-实现自定义的用户认证体系,原来的项目用的spring security版本比较低,改成了 spring-security-6.2.1 版本的,该项目前后端不分离的,基于 session 来认证用户是否登录

框架信息

boot_3.2.2 分支使用的框架信息

名称版本信息说明
JDK17LTS 长期支持版本
spring-boot-starter-web3.2.2内嵌web服务器, jar包启动
spring-boot-starter-security3.2.2安全框架
mybatis-plus-spring-boot3-starter3.5.5ORM框架
mybatis-plus-generator3.5.5根据数据表自动生产代码
spring-boot-starter-thymeleaf3.2.2处理静态资源,模板数据填充

代码分析

启动项目之后,访问 http://localhost:8080/main地址,会重定向到默认登录页, 登录认证之后会重定向到main页面
在这里插入图片描述
重定向到默认页面的过程可以查看之前的博客spring-security 默认登录页面(一)。整个过程还有几个问题需要分析

  1. 默认登录页登录接口的执行逻辑
  2. 登录认证成功之后重定向到main页面过程

配置类解析

配置类代码如下

package com.lagou.springsecurity.config;

import com.lagou.springsecurity.service.AuthenticationProviderService;
import com.lagou.springsecurity.service.CustomUserDetailsService;
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.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    private AuthenticationProviderService authenticationProvider;

    private CustomUserDetailsService customUserDetailsService;

    public SecurityConfig(AuthenticationProviderService authenticationProvider,
                          CustomUserDetailsService customUserDetailsService) {
        this.authenticationProvider = authenticationProvider;
        this.customUserDetailsService = customUserDetailsService;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.formLogin(httpSecurityFormLoginConfigurer ->
                httpSecurityFormLoginConfigurer.defaultSuccessUrl("/main", true));
        http.authorizeHttpRequests((authorizeHttpRequests) ->
                authorizeHttpRequests.anyRequest().authenticated());
        http.authenticationProvider(authenticationProvider);
        http.userDetailsService(customUserDetailsService);
        return http.build();
    }
}
  1. http.formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer.defaultSuccessUrl("/main", true)); 配置登录成功之后的跳转页面,本章续会分析这个过程
  2. http.authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests.anyRequest().authenticated()); 配置所有的地址都需要认证,这个配置会在AuthorizationFilter 中读取到,与当前的用户权限对比,看能否访问对应的资源,如果不能抛出异常给ExceptionTranslationFilter 过滤器处理
  3. http.authenticationProvider(authenticationProvider) 配置自定义的登录验证处理逻辑,验证用户名、密码,设置用户权限等
  4. http.userDetailsService(customUserDetailsService) 配置自定义的用户信息接口,根据用户名加载用户信息

默认登录页登录接口执行逻辑

  1. org.springframework.security.web.FilterChainProxy.VirtualFilterChain#doFilter 方法中增加断点,方便调试每个过滤器
    在这里插入图片描述
    可以看到当前项目配置的过滤器详情
    在这里插入图片描述

登录认证成功之后重定向到main页面过程

未登录之前访问 /main

  1. org.springframework.security.web.savedrequest.RequestCacheAwareFilter 过滤器会将请求缓存
  2. org.springframework.security.web.access.intercept.AuthorizationFilter 过滤去认证抛出异常
    在这里插入图片描述
  3. 异常处理过滤器 org.springframework.security.web.access.ExceptionTranslationFilter 处理异常
    在这里插入图片描述
    在这里插入图片描述
    生成重定向url http://localhost:8080/login
    在这里插入图片描述

生成默认登录页

https://blog.csdn.net/modelmd/article/details/135982664
在这里插入图片描述

点击登录

点击登录会调用 /login 接口,在 org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter 中进行用户名、密码的验证,UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter,大多数处理流程在 AbstractAuthenticationProcessingFilter中执行
在这里插入图片描述
流程图如下

Created with Raphaël 2.3.0 开始 用户名、密码认证 判断请求地址是否需要认证? 执行认证流程 用户名密码校验成功? 修改会话ID、CSRF token 设置认证成功,重定向到登录成功页 执行结束 return ; 结束 yes no yes no
  1. 用户名密码校验详细过程解析
    在方法 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter#attemptAuthentication 执行用户认证的逻辑
    在这里插入图片描述
    从请求头中获取用户名、密码
    在这里插入图片描述
    AuthenticationManager 类负责执行用户认证的逻辑,具体实现逻辑在类 org.springframework.security.authentication.ProviderManager
    在这里插入图片描述
    核心认证逻辑方法org.springframework.security.authentication.ProviderManager#authenticate
    在这里插入图片描述
    最终会进入用户自定义的用户名密码逻辑,在认证方法中可以将用户的权限加载到认证对象,这样AuthorizationFilter 就可以验证用户否有权限访问对应的url
    在这里插入图片描述
    在这里插入图片描述

  2. 修改会话ID、CSRF token
    在这里插入图片描述
    org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy修改请求的 sessionId, 防止固定会话攻击,org.springframework.security.web.csrf.CsrfAuthenticationStrategy更新seesion对应的 CSRF token

  3. 设置认证成功,重定向到登录成功页
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter#successfulAuthentication方法执行认证成功之后的相关逻辑。安全上下文SecurityContext设置认证成功的对象,安全上下文基于ThreadLocal实现的,在同一线程的其它filter中可以比较容易获取到认证成功的对象数据
    在这里插入图片描述
    SecurityContext中设置上下文对象之后,也会在 httpSeesion、httpRequest属性中存储认证对象,可以查看 org.springframework.security.web.context.SecurityContextRepository#saveContext方法。HttpSessionSecurityContextRepository将认证对象存储在 seesion ,RequestAttributeSecurityContextRepository将认证对象存储在http请求头属性
    在这里插入图片描述
    存储在 session的 key 默认值是 SPRING_SECURITY_CONTEXT
    在这里插入图片描述
    存储在 httpRequest 属性中的 key 默认值是 org.springframework.security.web.context.RequestAttributeSecurityContextRepository.SPRING_SECURITY_CONTEXT
    在这里插入图片描述
    重定向到缓存页。首先从session中获取缓存信息,然后重定向到具体的地址,可以查看org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler#onAuthenticationSuccess方法
    在这里插入图片描述
    从session缓存中获取 url
    在这里插入图片描述
    session缓存中未获取到 url, 去目标url处理器中查找 org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler#handle
    在这里插入图片描述

AbstractAuthenticationTargetUrlRequestHandler中目标defaultTargetUrl如何初始化的?
在配置类中初始化配置登录成功的地址
在这里插入图片描述

登录之后访问 /main

执行流程

  1. AnonymousAuthenticationFilter 中设置认证对象
    在这里插入图片描述

  2. 认证过滤器AuthorizationFilter 中会获取 session 中的已认证的用户
    在这里插入图片描述
    校验用户权限 org.springframework.security.authorization.AuthenticatedAuthorizationManager#check
    在这里插入图片描述
    获取已认证用户对象,org.springframework.security.web.access.intercept.AuthorizationFilter#getAuthentication
    在这里插入图片描述
    从session 中获取认证对象 org.springframework.security.web.context.HttpSessionSecurityContextRepository#loadDeferredContext,
    org.springframework.security.web.context.HttpSessionSecurityContextRepository#readSecurityContextFromSession
    在这里插入图片描述
    在这里插入图片描述
    获取之前登录的时候设置到 session 中的用户,属性key 和之前登录一致的 SPRING_SECURITY_CONTEXT
    在这里插入图片描述

清空认证信息

如果将cookie 清除之后,页面就会重新跳转到登录页

  1. 清除 cookie,在开发者工具中,删除对应的 session
    在这里插入图片描述
  2. 访问 http://localhost:8080/main 地址,丛session中获取认证信息失败,会重定向到登录页
    在这里插入图片描述
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcoder Day27| 贪心算法part01

语言:Java/Go 理论 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 什么时候用贪心?可以用局部最优退出全局最优,并且想不到反例到情况 贪心的一般解题步骤 将问题分解为若干个子问题找出适合的贪心策略求解每一个子…

数据类型和变量

1.数据类型 在Java中数据类型主要分为两类:基本数据类型和引用数据类型。 基本数据类型有四类八种: 1. 四类:整型、浮点型、字符型以及布尔型 2.八种: 整形是分为如上四种 byte short int long 浮点型分为 float 和double …

【Java EE】线程安全的集合类

目录 🌴多线程环境使用 ArrayList🎍多线程环境使⽤队列🍀多线程环境使⽤哈希表🌸 Hashtable🌸ConcurrentHashMap ⭕相关面试题🔥其他常⻅问题 原来的集合类, 大部分都不是线程安全的. Vector, Stack, HashT…

Java---文件,流✨❤️

文章目录 1.遍历文件夹2.遍历子文件夹3.练习流4.以字节流的形式读取文件内容5.以字节流的形式向文件写入数据顶折纠问6 .写入数据到文件 1.遍历文件夹 一般说来操作系统都会安装在C盘,所以会有一个 C:\WINDOWS目录。 遍历这个目录下所有的文件(不用遍历子目录) 找出…

全栈入门,前后端入门--springboot3+vue3制作一个后台管理项目

一:前言 1:因为本人也是全栈初学者,现在主职是公司前端,鉴于当前行业形式,单单只掌握一门语言已经不再吃香,甚至有点危险,35岁危机极大可能提前。作为00后要始终保持危机意识,不至于…

[C++]使用纯opencv去部署yolov9的onnx模型

【介绍】 部署 YOLOv9 ONNX 模型在 OpenCV 的 C 环境中涉及一系列步骤。以下是一个简化的部署方案概述,以及相关的文案。 部署方案概述: 模型准备:首先,你需要确保你有 YOLOv9 的 ONNX 模型文件。这个文件包含了模型的结构和权…

opencv生成一张图片

opencv也可以创造出一张照片&#xff0c;下面就是创造一张照片&#xff0c;并存放到项目文件夹下的示例 #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <vector> using namespace cv…

sql注入之sqli-labs-less-2 数值型报错注入

输入?id1 进行试探,第二关数值型&#xff0c;没有字符串的单引号&#xff0c;所以输入单引号报错&#xff0c; 经试探?id1 order by 5 -- 如果是错误的数值&#xff0c;显示如下&#xff1a; 正确 的为&#xff1a; ?id1 order by 3 -- 进行注入查看回显点&#xff1a; …

个体工商户营业执照怎么在网上年检?

第一步PC端登录国家企业信用信息公示系统&#xff01; 第二步点企业信息填报&#xff01; 第三步选择省份&#xff01; 第四步登陆方式&#xff01; 第五步点左上角年度报告填写&#xff01; 第六步下滑浏览点确认&#xff01; 第七步按照实际情况填写&#xff01; 第八步…

Linux笔记--文件权限

一、相关概念 Linux最优秀的地方之一就在于多人多任务环境。为了让各个使用者有较为保密的文件数据&#xff0c;文件的权限管理尤为重要。 ●文件的可存取身份: owner:文件拥有者 group:文件所属用户组 others:其他人 ●文件权限: r: read&#xff0c;读 文件:是否能查看文件内…

代码随想录刷题笔记 DAY 41 | 整数拆分 No.343 | 不同的二叉搜索树 No.96

文章目录 Day 4101. 整数拆分&#xff08;No. 343&#xff09;<1> 题目<2> 笔记<3> 代码 02. 不同的二叉搜索树&#xff08;No. 96&#xff09;<1> 题目<2> 笔记<3> 代码 Day 41 01. 整数拆分&#xff08;No. 343&#xff09; 题目链接 …

2024.3.1 小项目

1、机械臂 #include <myhead.h> #define SER_IP "192.168.125.32" //服务器端IP #define SER_PORT 8888 //服务器端端口号#define CLI_IP "192.168.68.148" //客户端IP #define CLI_PORT 9999 /…

Mybatis plus扩展功能-Db静态工具

目录 1 前言 2 使用方法 2.1 Db静态工具拥有的部分方法 2.2 举例 1 前言 在我们的服务层中&#xff0c;有时为了实现一个方法需要引入其它的Mapper层方法&#xff0c;但是&#xff0c;这样可能出现循环依赖。虽然Spring已经给我们解决了简单的循环依赖问题&#xff0c;但是…

【书生·浦语大模型实战营】第4节 课后作业

XTuner 大模型单卡低成本微调实战 0. 课程链接1. 课后作业1.2 进阶作业 0. 课程链接 课程链接&#xff1a;https://github.com/InternLM/tutorial/blob/main/xtuner/README.md 1. 课后作业 构建数据集&#xff0c;使用 XTuner 微调 InternLM-Chat-7B 模型, 让模型学习到它是你…

数字化转型导师坚鹏:证券公司数字化思维升级之道

证券公司数字化思维升级之道 ——数字化思维之六脉神剑 课程背景&#xff1a; 很多证券公司存在以下问题&#xff1a; 不知道数字化转型如何改变思维模式&#xff1f; 不清楚需要建立什么样的数字化思维&#xff1f; 不知道如何开展数字化思维提升工作&#xff1f; 课…

Redis小白入门教程

Redis入门教程 1. Redis入门1.1 Redis简介1.2 Redis服务启动与停止1.2.1 Redis下载1.2.2 服务启动命令1.2.3 客户端连接命令1.2.4 修改Redis配置文件 2. Redis数据类型2.1 五种常用数据类型介绍2.1.1 字符串操作命令2.1.2 哈希操作命令2.1.3 列表操作命令2.1.4 集合操作命令2.1…

JWT的原理与隐患

什么是JWT JWT通常由三部分组成&#xff1a;头信息&#xff08;header&#xff09;, 消息体&#xff08;payload&#xff09;和签名&#xff08;signature&#xff09;。 头信息指定了该JWT使用的签名算法 header {"alg":"HS256","typ":"…

9.8分割等和子集(LC416-M)

算法&#xff1a; 可以转换为背包问题&#xff1a; 一个商品如果可以重复多次放入是完全背包&#xff0c;而只能放入一次是01背包&#xff0c;写法还是不一样的。 要明确本题中我们要使用的是01背包&#xff0c;因为元素我们只能用一次。 只有确定了如下四点&#xff0c;才能…

C++_程序流程结构_循环结构_while

while循环结构 作用 满足循环条件&#xff0c;执行循环语句 语法 while (循环条件&#xff09;{循环语句}解释 只要循环条件的结果为真&#xff0c;就执行循环语句 流程图 示例 注意 在执行循环语句时候&#xff0c;程序必须提供跳出循环的出口&#xff0c;否则出现死循…

B083-SpringCloud-eureka ribbon feign hystrix

目录 eureka基础项目准备注册中心的搭建生产者注册到eureka消费者注册到eureka并通过eureka调用生产者eureka集群 服务提供者集群集群以后消费者调用服务的问题ribbon消费者使用ribbon负载均衡赋值负载均衡策略负载均衡优化 feignHystrixHystrix概述Ribbon搭配Hystrix降级处理F…