当前位置: 首页 > news >正文

Spring Security 基础配置详解(附Demo)

目录

  • 前言
  • 1. 基本知识
  • 2. Demo
  • 3. 实战

前言

基本的Java知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

1. 基本知识

HttpSecurity 是 Spring Security 的核心类之一,负责配置基于 HTTP 的安全性,提供了用于定义安全规则、身份验证、授权、会话管理、跨站请求伪造(CSRF)保护等一系列功能的 API

HttpSecurity 主要知识点

功能方法说明
认证机制配置.authorizeRequests()用于定义请求的访问权限规则。例如,哪些 URL 需要认证,哪些允许匿名访问
禁用 CSRF 保护.csrf().disable()CSRF 是跨站请求伪造,默认启用。可以使用此方法禁用它
跨域资源共享(CORS).cors()允许配置跨域请求处理。通常用于解决跨域资源共享问题
表单登录.formLogin()使用表单认证方式,配置登录页面、登录处理 URL 等
HTTP Basic 认证.httpBasic()使用 HTTP Basic 认证方式,在每个请求的 Authorization 头中传递凭据
会话管理.sessionManagement()定义会话的管理方式,比如会话超时、是否创建新会话、并发会话控制等
记住我功能.rememberMe()允许用户通过“记住我”功能进行持久化登录
异常处理.exceptionHandling()配置访问被拒绝时的处理器或未登录时的处理行为
用户登出.logout()配置登出功能,包括登出 URL、清除 Cookie、登出成功后的跳转页面等
自定义过滤器.addFilter() / .addFilterBefore() / .addFilterAfter()添加自定义过滤器,可以在指定的过滤器链中插入额外的处理逻辑
禁用默认的头部配置.headers().disable()禁用默认的安全头部配置,例如 X-Content-Type-Options、X-Frame-Options 等
强制 HTTPS.requiresChannel()配置强制 HTTPS 的通道安全

基本的一个配置过程如下:

  1. 身份验证和授权:通过 .authorizeRequests() 设置每个 URL 的访问权限
  2. 会话管理:使用 .sessionManagement() 管理会话行为,包括并发会话和超时
  3. 异常处理:通过 .exceptionHandling() 定义未授权请求的处理逻辑
  4. 跨域配置:使用 .cors() 和 .csrf() 设置跨域和跨站请求伪造保护
  5. 自定义过滤器:通过 .addFilter() 方法插入自定义过滤器,以实现更多灵活的安全控制

2. Demo

给一个基本的Demo复杂场景示例:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http// 1. 禁用 CSRF 保护(根据需要禁用).csrf().disable()// 2. 开启 CORS 支持.cors().and()// 3. 配置授权规则.authorizeRequests()// 允许静态资源和主页访问.antMatchers("/", "/home", "/css/**", "/js/**").permitAll()// 需要用户登录的请求.antMatchers("/user/**").authenticated()// 只允许 ADMIN 角色访问的请求.antMatchers("/admin/**").hasRole("ADMIN")// 所有其他请求需要认证.anyRequest().authenticated()// 4. 表单登录配置.and().formLogin().loginPage("/login")               // 自定义登录页面.loginProcessingUrl("/perform_login") // 登录表单提交 URL.defaultSuccessUrl("/home", true)    // 登录成功后跳转的默认页面.failureUrl("/login?error=true")    // 登录失败后跳转的页面.permitAll()                        // 允许所有人访问登录页面// 5. 记住我功能.and().rememberMe().key("uniqueAndSecret")             // rememberMe 的密钥.tokenValiditySeconds(86400)        // token 有效期 1 天// 6. HTTP Basic 认证.and().httpBasic()                             // 启用 HTTP Basic 验证// 7. 配置登出功能.and().logout().logoutUrl("/perform_logout")        // 自定义登出 URL.deleteCookies("JSESSIONID")         // 删除 session ID 的 cookie.logoutSuccessUrl("/login?logout")   // 登出成功后跳转页面.permitAll()// 8. 配置异常处理.and().exceptionHandling().accessDeniedPage("/403")            // 无权限时跳转到 403 页面// 9. 会话管理.and().sessionManagement().maximumSessions(1)                  // 限制最多 1 个并发会话.maxSessionsPreventsLogin(true);     // 超过限制时不允许再次登录}
}

3. 实战

为更好的展示案例,以JimuReport报表为例

在这里插入图片描述

详细分析其代码含义:

@Configuration
@EnableWebSecurity // 启用 Spring Security 的Web安全功能
public class SpringSecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {// 禁用 CSRF 保护http.csrf().disable().authorizeRequests() // 开始定义请求的授权规则// 允许所有人访问登录相关的请求.antMatchers("/login/**").permitAll()// 允许访问静态资源,放行相关路径.antMatchers("/jmreport/**/cdn/**", // CDN 资源"/jmreport/desreport_/**/*.js", // JavaScript 文件"/jmreport/desreport_/**/*.css", // CSS 文件"/jmreport/desreport_/**/*.png") // PNG 图片.permitAll()// 允许访问无需登录的接口.antMatchers("/jmreport/excelQueryByTemplate", // 模板查询接口"/jmreport/img/**", // 图片接口"/jmreport/download/image", // 下载图片接口"/jmreport/verificationToken", // 验证令牌接口"/jmreport/link/queryByIds", // 查询链接的接口"/jmreport/test/getUserMsg", // 获取用户信息接口"/jmreport/test/getOrder", // 获取订单接口"/jmreport/auto/export/download/**") // 导出下载接口.permitAll()// 允许访问分享页面相关接口.antMatchers("/jmreport/shareView/**", // 分享视图"/jmreport/checkParam/**", // 检查参数"/jmreport/share/verification", // 分享验证"/jmreport/getQueryInfo", // 获取查询信息"/jmreport/show", // 显示接口"/jmreport/addViewCount/**") // 增加访问量接口.permitAll()// 允许访问 view 页面,使用自定义访问控制逻辑.antMatchers("/jmreport/view/**").access("@viewPageCustomAccess.check(request,authentication)")// 任何其他请求必须经过身份验证.anyRequest().authenticated().and()// 配置表单登录.formLogin().loginPage("/login/login.html") // 自定义登录页面.loginProcessingUrl("/login") // 登录请求处理的 URL.successHandler(new CustomLoginSuccessHandler()) // 登录成功处理器.permitAll() // 允许所有人访问登录页面.and()// 配置登出.logout().invalidateHttpSession(true) // 登出时无效化 HTTP 会话.clearAuthentication(true) // 清除认证信息.permitAll(); // 允许所有人访问登出功能return http.build(); // 构建 SecurityFilterChain}
}

另外一个实战代码示例:

@Bean
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {// 开启跨域保护httpSecurity// 开启跨域资源共享(CORS).cors().and()// 禁用 CSRF(因为不使用 Session 机制,使用 Token 验证).csrf().disable()// 配置 Session 管理为无状态,因为基于 Token 机制,不需要会话.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()// 关闭浏览器框架选项(防止点击劫持).headers().frameOptions().disable().and()// 配置自定义的异常处理器.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint) // 处理未认证用户的访问异常.accessDeniedHandler(accessDeniedHandler); // 处理已认证用户的访问权限异常// 使用自定义的登录机制,不依赖 Spring Security 自带的登录逻辑// 登录暂时不使用 Spring Security 的扩展点,以减少复杂度和用户学习成本// 获取 @PermitAll 注解标注的 URL 列表,这些 URL 免登录Multimap<HttpMethod, String> permitAllUrls = getPermitAllUrlsFromAnnotations();// 配置请求权限httpSecurity// 定义授权规则.authorizeRequests()// ① 全局共享规则// 1.1 静态资源可以匿名访问.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()// 1.2 设置 @PermitAll 标注的接口无需认证.antMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll().antMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll().antMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll().antMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll()// 1.3 基于配置文件中的 permit-all-urls,无需认证.antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()// 1.4 设置应用 API(如 `/app/api/**`),无需认证.antMatchers(buildAppApi("/**")).permitAll()// 1.5 验证码接口允许匿名访问.antMatchers("/captcha/get", "/captcha/check").permitAll()// ② 各个模块的自定义规则(通过 registry 定制).and().authorizeRequests(registry -> authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry)))// ③ 兜底规则,其他请求必须认证.authorizeRequests().anyRequest().authenticated();// 在 UsernamePasswordAuthenticationFilter 前添加 Token 过滤器,用于 Token 验证httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);// 返回配置好的 SecurityFilterChainreturn httpSecurity.build();
}

相关文章:

Spring Security 基础配置详解(附Demo)

目录 前言1. 基本知识2. Demo3. 实战 前言 基本的Java知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;【Java项目】实战CRUD的功能整理&#xff08;持续更新&#xff09; 1. 基本知识 HttpSecurity 是 Spri…...

代码随想录打卡Day1

文章目录 day011 数组理论基础2 二分查找法3 移除元素4 平方数 day01 Java JDK是17.0.11 1 数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合。 数组下标都是从0开始的。 数组内存空间的地址是连续的。 因为数组在内存空间的地址是连续的&#xff0c;所以我们…...

Vue快速创建工程+Element Plus

创建Vue工程 执行命令 npm init vuelatest 执行这两个绿色的命令 执行这个命令启动 npm run dev Element 打开网站https://element-plus.org/zh-CN/ npm install element-plus --save 然后在vscode中打开你的项目工程 // main.ts import { createApp } from vue import Ele…...

汽车管理系统——主界面制作

目录 主界面需要有什么&#xff1f;然后要做什么&#xff1f;添加两个主菜单&#xff08;声明&#xff09;下一步应该干什么&#xff1f;能够跳转到文件有哪几个动作&#xff1f;动作如何声明&#xff1f;为什么用选择声明指针&#xff0c;不选择直接声明这个对象&#xff1f; …...

C++ 右值引用深入理解:特性、优化与底层

目录 一、左右值的概念及右值的种类 二、左值引用与右值引用 左值引用给右值取别名&#xff1a; 右值引用给左值取别名&#xff1a; 三、引用的意义及左值引用的场景 四、移动构造&#xff1a; 右值引用在底层里的实现&#xff1a; 一、左右值的概念及右值的种类 在 C …...

C# 文件操作

文章目录 文件系统FileInfo和DirectoryInfo类完成一个文件的拷贝判断一个文件是否存在FileInfo和DirectoryInfo的属性列表FileInfo和DirectoryInfo的方法列表读写文件文件系统 下面的类用于浏览文件系统和执行操作,比如移动,复制和删除文件。 System.MarshalByRefObject 这个…...

FFmpeg 4.3 音视频-多路H265监控录放C++开发三 :安装QT5.14.2, 并将QT集成 到 VS2019中。

一&#xff0c;安装QT&#xff0c; 重点&#xff1a;在安装QT的时候要安装msvc201x版本的组件&#xff0c; 二 &#xff0c; 安装 qt-vs-tools Index of /development_releases/vsaddin/2.8.1 三&#xff0c;需要安装过 windows10 SDK&#xff0c;一般我们在安装vs2019的时候就…...

Linux 累加计算递归算法汇编实现

1...n可以使用公式计算&#xff0c;同时也是递归实现的很好例子&#xff0c;其c实现代码为 int f(int i) {i && (if(i-1));return i; } 其终止条件为0&#xff0c;此时i && &#xff08;if(i-1)&#xff09;表达式不成立&#xff0c;不计算if(i-1)直接返回0&…...

明日周刊-第23期

十月已过半&#xff0c;气温也转凉了&#xff0c;大家注意保温哦。冬吃萝卜&#xff0c;夏吃姜&#xff0c;在快要到来的冬季大家可以选择多吃点萝卜。 配图是本周末去商场抓娃娃的时候拍的照片&#xff0c;现在抓娃娃单次普遍都控制在1块钱以下了&#xff0c;还记得多年前的抓…...

kubernets(二)

集群操作 查看集群信息 kubectl get查看各组件信息 格式&#xff1a;kubectl get 资源类型 【资源名】 【选项】 events #查看集群中的所有日志信息 -o wide # 显示资源详细信息&#xff0c;包括节点、地址... -o yaml/json #将当前资源对象输出至 yaml/json 格式文…...

《YOLO 标注工具全览》

《YOLO 标注工具全览》 一、YOLO 标注工具的重要性二、常见的 YOLO 标注工具介绍&#xff08;一&#xff09;LabelImg&#xff08;二&#xff09;Yolo_Label&#xff08;三&#xff09;在线标注工具 Make Sense&#xff08;四&#xff09;Ybat - YOLO BBox Annotation Tool&…...

财富思维学习

四大象限&#xff1a; 人类财富创造史经历的五个阶段&#xff1a; 1、黄色&#xff08;土地&#xff09;财务阶段&#xff1a;拥有土地和劳动力是财富的要求 2、蓝色&#xff08;海&#xff09;财富阶段&#xff1a;谁拥有贸易的通道谁就拥有财富&#xff08;如港口&#xff…...

python爬虫加解密分析及实现

第一种&#xff1a; 1、找到加密的接口地址&#xff0c;通过加密的接口地址全局搜索 2、通过打断点的方式&#xff0c;操作页面&#xff0c;跑到断点处时&#xff0c;即可找到加密串&#xff0c;如图二&#xff1b; 3、找到用的是哪种加密方式&#xff0c;如&#xff1a; cr…...

用Java做智能客服,基于私有知识库

构建Java智能客服系统的整体思路 使用Java构建智能客服系统的整体思路是&#xff1a; 首先将客服QA文档以Word形式导入到系统中&#xff0c;通过向量化处理存入知识库。 当用户提出问题时&#xff0c;系统会根据问题内容从知识库中检索相关的上下文信息&#xff0c;并结合大…...

软考(网工)——网络安全

文章目录 &#x1f550;网络安全基础1️⃣网络安全威胁类型2️⃣网络攻击类型 &#x1f551;现代加密技术1️⃣私钥密码/对称密码体制2️⃣对称加密算法总结3️⃣公钥密码/非对称密码4️⃣混合密码5️⃣国产加密算法 - SM 系列6️⃣认证7️⃣基于公钥的认证 &#x1f552;Hash …...

如何给手机换ip地址

在当今数字化时代&#xff0c;IP地址作为设备在网络中的唯一标识&#xff0c;扮演着举足轻重的角色。然而&#xff0c;有时出于隐私保护、网络访问需求或其他特定原因&#xff0c;我们可能需要更改手机的IP地址。本文将详细介绍几种实用的方法&#xff0c;帮助您轻松实现手机IP…...

kafkamanager安装

一.下载kafkamanager2.0 https://download.csdn.net/download/cyw8998/89892482 二.修改配置文件 解压缩 unzip kafka-manager-2.0.0.0.zip vim application.conf /opt/module/kafka-manager-2.0.0.0/conf/application.conf 添加以下内容&#xff1a;&#xff08;连接zooke…...

笔记本电脑U口保护分享

在前司时候&#xff0c;经常遇到各种硬件类的问题&#xff0c;但是之前没时间分享&#xff0c;现在来给大家分享一下&#xff0c;常见的问题及如何保护。 1.接口接触不良。这个一般发生于使用时间长了&#xff0c;可以用细砂纸&#xff0c;轻轻摩擦后再进行尝试。 2.接口失灵…...

OpenCV高级图形用户界面(20)更改窗口的标题函数setWindowTitle()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在OpenCV中&#xff0c;cv::setWindowTitle函数用于更改窗口的标题。这使得您可以在程序运行时动态地更改窗口的标题文本。 函数原型 void cv::…...

结构体指针的初始化以及结构体变量作为函数实参传递时易混淆的知识点

结构体指针初始化以及结构体变量作为函数实参传递时易混淆的知识点 首先要明确&#xff0c;结构体类型是用户自己定义的一种数据类型&#xff0c;其本质上与int, char等标准数据类型是一致的 **1.**因此&#xff0c;在进行结构体指针的初始化时&#xff0c;应该这样写&#x…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...