【SpringBoot3】Spring Security 常用配置总结

注:本文基于Spring Boot 3.2.1 以及 Spring Security 6.2.1

相关文章

【SpringBoot3】Spring Security 核心概念
【SpringBoot3】Spring Security 常用注解
【SpringBoot3】Spring Security 详细使用实例(简单使用、JWT模式)
【SpringBoot3】Spring Security使用mybatis-plus存储用户角色权限,实现动态权限处理

一、Spring Security 常用配置总结

1、记住我 rememberMe

1)配置HttpSecurity,如下代码

// 开启rememberMe,登录表单增加 <input type="checkbox" name="remember-me">
http.rememberMe(Customizer.withDefaults());

2)登录表单页面增加勾选参数,在登录时勾选即可

注意参数名remember-me是默认的,也可以通过配置修改

<input type="checkbox" name="remember-me">

登录成功后,会生成一个cookie(remember-me)

3)配置rememberMe其他参数

  • rememberMeParameter,表单参数名称
  • rememberMeCookieName,记录在浏览器的cookieName
  • tokenValiditySeconds,有效时间,单位秒
http.rememberMe(rm -> rm.rememberMeParameter("rememberMe").rememberMeCookieName("rememberMeCookieName").key("rememberMe").tokenValiditySeconds(1800));

2、退出处理

// 退出时,设置session无效
http.logout(logout -> logout.invalidateHttpSession(true));

3、持久化登录令牌

持久化登录令牌是记住我功能的补充,可以将登录的token存储在数据库中。

参考 JdbcTokenRepositoryImpl 可以得知需要创建一张表 persistent_logins

本例使用 mybatis-plus + mysql 存储

1)创建持久化令牌表 persistent_logins

create table persistent_logins (username varchar(64) not null, series varchar(64) primary key,  token varchar(64) not null, last_used timestamp not null)

2)创建实体和Mapper

@Data
@TableName("persistent_logins")
public class UserToken {private String username;private String series;@TableField("token")private String tokenValue;@TableField("last_used")private Date date;
}@Mapper
public interface UserTokenMapper extends BaseMapper<UserToken> {
}

3)创建自定义持久化类 MyPersistentTokenRepositoryImpl 实现接口 PersistentTokenRepository

@Service
public class MyPersistentTokenRepositoryImpl implements PersistentTokenRepository {@Resourceprivate UserTokenMapper userTokenMapper;@Overridepublic void createNewToken(PersistentRememberMeToken token) {UserToken userToken = BeanUtil.toBean(token, UserToken.class);userTokenMapper.insert(userToken);}@Overridepublic void updateToken(String series, String tokenValue, Date lastUsed) {LambdaUpdateWrapper<UserToken> updateWrapper = Wrappers.lambdaUpdate();updateWrapper.eq(UserToken::getSeries, series).set(UserToken::getTokenValue, tokenValue).set(UserToken::getDate, lastUsed);userTokenMapper.update(updateWrapper);}@Overridepublic PersistentRememberMeToken getTokenForSeries(String seriesId) {UserToken userToken = userTokenMapper.selectOne(new LambdaQueryWrapper<UserToken>().eq(UserToken::getSeries, seriesId));PersistentRememberMeToken meToken = BeanUtil.toBean(userToken, PersistentRememberMeToken.class);return meToken;}@Overridepublic void removeUserTokens(String username) {userTokenMapper.delete(new LambdaQueryWrapper<UserToken>().eq(UserToken::getUsername, username));}
}

4)在 HttpSecurity 中配置使用

@Resource
private MyPersistentTokenRepositoryImpl tokenRepository;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {// --- 忽略其他代码 --- //http.rememberMe(rm -> rm.rememberMeParameter("rememberMe").rememberMeCookieName("rememberMeCookieName").key("rememberMe")// 配置持久化类.tokenRepository(tokenRepository).tokenValiditySeconds(1800));// --- 忽略其他代码 --- //
}

5)登录,勾选记住我
在这里插入图片描述
打开数据库查看,存储正常

在这里插入图片描述

4、并发登录控制,后登录踢掉前面登录

设置每个账户最大的session数量

// 每个账户最大的session数量
http.sessionManagement(sm->sm.maximumSessions(1));

5、主动踢人下线

1)配置 SessionRegistry

/*** 通过 SessionRegistry 可以获取到当前登录的所有用户* @return*/
@Bean
public SessionRegistry sessionRegistry(){return new SessionRegistryImpl();
}

在 HttpSecurity 中配置

// 每个账户最大的session数量,配置 sessionRegistry
http.sessionManagement(sm->sm.maximumSessions(1).sessionRegistry(sessionRegistry()));

2)在controller中获取在线用户,并展示

@GetMapping("/index")
public String index(Model model) {// 获取所有登录过的用户List<Object> allPrincipals = sessionRegistry.getAllPrincipals();// 移除不存在session的用户List<Object> list = allPrincipals.stream().filter(p -> {List<SessionInformation> allSessions = sessionRegistry.getAllSessions(p, false);return !allSessions.isEmpty();}).toList();model.addAttribute("users", list);return "index";
}

在 index.html中显示

<table><tr><th>用户名</th><th>操作</th></tr><tr th:each="user:${users}"><td th:text="${user.username}"></td><td><a th:href="@{/kickout(username=${user.username})}">下线</a></td></tr>
</table>

3)增加踢人接口

@GetMapping("/kickout")
public String kickout(String username) {List<Object> allPrincipals = sessionRegistry.getAllPrincipals();for (Object principal : allPrincipals) {List<SessionInformation> allSessions = sessionRegistry.getAllSessions(principal, false);User user = (User) principal;if (user.getUsername().equals(username)) {//将所有已登录的 session 都失效allSessions.forEach(SessionInformation::expireNow);}}return "redirect:/index";
}

6、允许跨域处理

什么是跨域

CORS跨域,全称是“跨域资源共享”(Cross-Origin Resource Sharing),是一种基于HTTP标头的机制,它允许服务器指示除其自身之外的任何来源(域、方案或端口),浏览器应允许从中加载资源。这种机制允许浏览器向跨源服务器发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

当浏览器从一个源(域)向另一个源(域)发出请求时,由于安全原因,浏览器会限制这种跨源请求。但是,CORS通过服务器和浏览器的协商,允许某些跨源请求得以通过。具体来说,浏览器会先向服务器发送一个“预检”请求,检查服务器是否允许实际请求。如果服务器允许,那么浏览器就会发送实际的跨域请求。

CORS需要浏览器和服务器同时支持,目前几乎所有的浏览器都支持CORS,但IE浏览器不能低于IE10版本。实现CORS的关键在于服务器,只要服务器实现了CORS接口,就可以实现跨域通信。

Spring Security 配置允许跨域

配置 HttpSecurity

// 开启跨域
http.cors(Customizer.withDefaults())

7、跨域攻击防护

什么是CSRF

CSRF,全称是跨站请求攻击(Cross-Site Request Forgery),是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。简单来说,攻击者通过一些技术手段欺骗用户的浏览器去访问一个用户之前已经认证过的站点,并运行一些操作,如发邮件、发消息,甚至进行财产操作(如转账和购买商品)等。由于浏览器之前已经认证过,被访问的站点会误以为是真正的用户操作而去运行。这种攻击利用了Web中用户身份认证验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。因此,CSRF攻击可以被理解为攻击者盗用了用户的身份,以用户的名义发送恶意请求。

为了防范CSRF攻击,Web应用程序可以采取一些措施,如使用验证码、检查请求来源、使用CSRF令牌等。这些措施可以增加攻击的难度,降低攻击成功的可能性。同时,用户也应该保持警惕,不要随意点击不明链接或下载未知来源的文件,以保护自己的隐私和财产安全。

Spring Security 处理 CSRF

默认情况下,Spring Security 会自动启用 CSRF 保护,这包括在表单中包含 CSRF 令牌(token)并在处理请求时验证这个令牌。

// 开启csrf 保护
http.csrf(Customizer.withDefaults());

在登录表单中,会自动生成参数_csrf ,如下所示:

在这里插入图片描述

参考

  • https://docs.spring.io/spring-security/reference/index.html

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

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

相关文章

【MATLAB GUI】 4. 坐标区和表

看B站up主freexyn的freexyn编程实例视频教程系列36Matlab GUI的学习笔记 文章目录 坐标区表 坐标区 任务要求设计一个图像显示界面&#xff0c;根据选定的周期做出相应的sin函数图像 使用坐标区、弹出式菜单、普通按钮设计页面&#xff0c;弹出式菜单string设置为1、2、3、4代…

【Linux系统化学习】深入理解匿名管道(pipe)和命名管道(fifo)

目录 进程间通信 进程间通信目的 进程间通信的方式 管道 System V IPC&#xff08;本地通信&#xff09; POSIX IPC&#xff08;网络通信&#xff09; 管道 什么是管道 匿名管道 匿名管道的创建 匿名管道的使用 匿名管道的四种情况 匿名管道的五种特性 命名管道 …

iOS总体框架介绍和详尽说明

iOS总体框架介绍和详尽说明 一、iOS是什么&#xff1f;1.iOS简述2.iOS界面 二、iOS总体框架介绍和详尽说明1.iOS的框架层级1. 核心操作系统层&#xff08;Core OS layer&#xff09;1.1 Accelerate Framework1.2 Core Bluetooth Framework1.3 External Accessory Framework1.4 …

【wails】(4):使用wails做桌面应用开发,整合chatgpt-web项目做前端,进行本地开发,web端也可以连调,使用websocket实现

1&#xff0c;视频地址 【wails】&#xff08;4&#xff09;&#xff1a;使用wails做桌面应用开发&#xff0c;整合chatgpt-web项目做前端&#xff0c;进行本地开发&#xff0c;web端也可以连调&#xff0c;使用websocket实现 2&#xff0c;演示效果 启动先是报500 错误&#…

Charles小程序抓包(安卓版)

微信小程序/公众号抓包的主流方式 目前有以下几种&#xff1a; 1、WindowsBurpProxifier&#xff08;配置困难&#xff0c;数据包卡顿) 2、Burp安卓模拟器&#xff08;模拟器卡顿&#xff09; 3、BurpCharles&#xff08;本文测试&#xff0c;抓包完整&#xff0c;放包流畅…

防御保护第八、九、十、十一天笔记

一、内容安全 1、DFI和DPI技术 --- 深度检测技术 DPI是一种基于应用层的流量检测和控制技术&#xff0c;它会对流量进行拆包&#xff0c;分析包头和应用层的内容&#xff0c;从而识别应用程序和应用程序的内容。这种技术增加了对应用层的分析&#xff0c;识别各种应用&#xf…

【2024.02.22】定时执行专家 V7.0 发布 - TimingExecutor V7.0 Release - 龙年春节重大更新版本

目录 ▉ 新版本 V7.0 下载地址 ▉ V7.0 新功能 ▼2024-02-21 V7.0 - 更新日志▼ ▉ V7.0 新UI设计 ▉ 新版本 V7.0 下载地址 BoomWorks软件的最新版本-CSDN博客文章浏览阅读10w次&#xff0c;点赞9次&#xff0c;收藏41次。▉定时执行专家—毫秒精度、专业级的定时任务执行…

Jenkins2.426邮件通知配置

之前安装的jenkins出现问题了&#xff0c;重新装了jenkins&#xff0c;需要重新配置&#xff1a;Maven&#xff0c;JDK&#xff0c;Allure报告&#xff0c;邮件通知&#xff0c;Extended E-mail Notification等 配置Maven&#xff0c;JDK参考&#xff1a;CICD集合(四):Jenkins…

vue中使用wangEditor富文本编辑器

jsd-2306-vue-01: 教学项目教学项目教学项目教学项目教学项目 2306-vue-baking-teacher: 教学项目教学项目教学项目教学项目 一、脚手架工程中使用富文本编辑器wangEditor 1.通过以下命令 安装wangEditor npm i wangeditor -S 2.在main.js文件中添加以下配置信息 //引入wa…

多数pythoneer只知有列表list却不知道python也有array数组

数组和列表 Python中数组和列表是不同的&#xff0c;我敢断言大多数的pythoneer只知道有列表list&#xff0c;却不知道python也有array数组。列表是一个包含不同数据类型的元素集合&#xff0c;而数组是一个只能含相同数据类型的元素集合。 Python的array库是一个提供数组操作…

第七篇【传奇开心果系列】python的文本和语音相互转换库技术点案例示例:Sphinx自动电话系统(IVR)经典案例

传奇开心果博文系列 系列博文目录python的文本和语音相互转换库技术点案例示例系列 博文目录前言一、雏形示例代码二、扩展思路介绍三、Sphinx多语言支持示例代码四、Sphinx和语音合成库集成示例代码五、Sphinx语音识别前自然语言预处理示例代码六、Sphinx语音识别自动电话系统…

echarts 实现x轴文字过长时折行展示

代码如下&#xff1a; this.options {color: ["#0075FF", "#00E2C4", "#FCA884", "#FFCB11"],grid: {top: "25%",bottom: "6%",right: "8%",left: "8%",containLabel: true,},legend: {top…

vscode怎么运行C++的cpp文件

非常简单&#xff0c;点击vscode导航栏的Extensions, 搜索C/C Compile Run安装上即可&#xff0c; 写好 C/C 程序之后&#xff0c;直接使用 F6 一键编译运行就能出结果。

robots.txt 文件规则

robots.txt 是一种用于网站根目录的文本文件&#xff0c;其主要目的在于指示网络爬虫&#xff08;web crawlers&#xff09;和其他网页机器人&#xff08;bots&#xff09;哪些页面可以抓取&#xff0c;以及哪些页面不应该被抓取。可以看作是网站和搜索引擎机器人之间的一个协议…

实验室预约|实验室预约小程序|基于微信小程序的实验室预约管理系统设计与实现(源码+数据库+文档)

实验室预约小程序目录 目录 基于微信小程序的实验室预约管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、微信小程序前台 2、管理员后台 &#xff08;1&#xff09;管理员登录 &#xff08;2&#xff09;实验室管理 &#xff08;3&#xff09;公告信息…

【数据分享】2014-2024年全国监测站点的逐年空气质量数据(15个指标\免费获取)

空气质量的好坏反映了空气的污染程度&#xff0c;在各项涉及城市环境的研究中&#xff0c;空气质量都是一个十分重要的指标。空气质量是依据空气中污染物浓度的高低来判断的。 我们发现学者王晓磊在自己的主页里面分享了2014年5月以来的全国范围的到站点的逐时空气质量数据&am…

PBM模型学习

本专栏着重讲解PBM学习所得&#xff0c;学习笔记、心得&#xff0c;并附有视频素材资料&#xff0c;视频详细目录如下&#xff1a; PBM相关参数解释1 PBM相关参数解释2 PBM相关案例实践1 PBM相关案例实践2 PBM相关案例实践2 PBM相关案例实践3 PBM多相流中次相界面设置1 PBM多相…

ERC404 + meme 文化叙事,Dancing Beans 会达到怎样的高度?

在十年以前&#xff0c;一个叫做《wow&#xff01;you can really dance》的鬼畜舞蹈视频&#xff0c;在互联网上刮起了一股 meme 浪潮&#xff0c;很多玩家将视频中跳舞的男主角的跳舞片段二次加工&#xff0c;进一步鬼畜化、做成表情包&#xff0c;并在各个社交平台疯传。与此…

SpringMVC 学习(二)之第一个 SpringMVC 案例

目录 1 通过 Maven 创建一个 JavaWeb 工程 2 配置 web.xml 文件 3 创建 SpringMVC 配置文件 spring-mvc.xml 4 创建控制器 HelloController 5 创建视图 index.jsp 和 success.jsp 6 运行过程 7 参考文档 1 通过 Maven 创建一个 JavaWeb 工程 可以参考以下博文&#x…

Linux命令之ls命令

ls命令 ls命令的作用是列出目录下的内容&#xff0c;语法如下&#xff1a; ls [ -a -l -h ] [ Linux路径 ] 1、 -a -l -h 是可选的选项。 2、Linux路径是此命令可选的参数。 当不使用选项和参数&#xff0c;直接使用 ls 命令本体&#xff0c;表示&#xff1a;以平…