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

SpringSecurity高级用法

SpringSecurity的高级用法,包括自定义loginUrl携带参数,自定义认证校验逻辑,自定义权限校验逻辑。 示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-advanced-security

一、概述

在项目实际开发过程中,SpringSecurity默认的认证和权限校验逻辑不能实现很高的业务复杂度,这种情况下我们需要自定义这些逻辑,包括自定义loginUrl携带参数,自定义认证校验逻辑,自定义权限校验逻辑。

二、自定义loginUrl携带参数

SpringSecurity在跳转login页面时,虽然可以指定login的url,但是无法让url中携带动态参数,不如跳转到login?param=foo,其中foo需要根据特定条件动态变化,要实现这种效果,我们需要通过exceptionHandling指定自定义LoginUrlAuthenticationEntryPoint。

public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();public CustomLoginUrlAuthenticationEntryPoint(String loginFormUrl) {super(loginFormUrl);}@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)throws IOException, ServletException {if (!super.isUseForward()) {String redirectUrl = this.buildRedirectUrlToLoginPage(request, response, authException);// change login urlredirectUrl = redirectUrl + "?param=test";this.redirectStrategy.sendRedirect(request, response, redirectUrl);} else {String redirectUrl = null;if (super.isForceHttps() && "http".equals(request.getScheme())) {redirectUrl = this.buildHttpsRedirectUrlForRequest(request);}if (redirectUrl != null) {this.redirectStrategy.sendRedirect(request, response, redirectUrl);} else {String loginForm = this.determineUrlToUseForThisRequest(request, response, authException);RequestDispatcher dispatcher = request.getRequestDispatcher(loginForm);dispatcher.forward(request, response);}}}
}

以上代码自定义CustomLoginUrlAuthenticationEntryPoint,在commence方法中我们可以按照业务需要实现自己的跳转逻辑,通过修改redirectUrl实现。

在SpringSecurity配置中通过exceptionHandling引用CustomLoginUrlAuthenticationEntryPoint:

exceptionHandling(customizer ->customizer.authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint("/login")))

三、自定义认证校验逻辑

SpringSecurity默认的认证逻辑是校验用户名密码是否合法,如果想增加其它的校验逻辑,需要实现AuthenticationProvider,然后在authenticationManager中指定我们自己实现的AuthenticationProvider。

public class CustomAuthenticationProvider extends DaoAuthenticationProvider {@Autowiredprivate CustomUserDetailsService customUserDetailsService;@PostConstructpublic void init() {this.setUserDetailsService(customUserDetailsService);}@Overrideprotected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) {super.additionalAuthenticationChecks(userDetails, authentication);HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();String username = userDetails.getUsername();// 自定义认证校验逻辑if (username.equals("need approval")) {log.info("invalid request is: {}", req);throw new AuthenticationServiceException("Your account is pending approval for access");}}
}

在上面自定义的CustomAuthenticationProvider中,通过重写additionalAuthenticationChecks方法进行自定义认证逻辑的实现。

然后在authenticationManager中指定CustomAuthenticationProvider:

@Bean
public AuthenticationManager authenticationManager() {return new ProviderManager(customAuthenticationProvider);
}

四、自定义权限校验逻辑

SpringSecurity可以通过在配置中通过requestMatchers指定较为灵活的权限校验策略,但是缺少一些动态特性,比如对 /foo/{param} 这种rest风格的带变量的url就处理不了,
这种情况我们可以通过自定义AuthorizationManager来实现,然后在requestMatchers中通过access方法来指定我们自定义的AuthorizationManager。

public class MyRequestAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {private final SecurityExpressionHandler<RequestAuthorizationContext> expressionHandler = new DefaultHttpSecurityExpressionHandler();public MyRequestAuthorizationManager() {}// 自定义授权校验逻辑@Overridepublic AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication, context);String checkParam = Optional.ofNullable(ctx.lookupVariable("param")).map(String::valueOf).orElse(null);// the '/public' url doesn't need authenticationif (checkParam != null && (checkParam.equals("public"))) {return new AuthorizationDecision(true);}return new AuthorizationDecision(!ObjectUtils.isEmpty(authentication.get().getCredentials()));}
}

在MyRequestAuthorizationManager中通过重写check方法来实现自定义权限校验,rest风格的带变量的url中的变量,可以通过EvaluationContext的lookupVariable方法获取变量值。

指定自定义AuthorizationManager:

MyRequestAuthorizationManager myRequestAuthorizationManager = new MyRequestAuthorizationManager();
http.authorizeHttpRequests(authorize -> authorize.requestMatchers("/{param}").access(myRequestAuthorizationManager))

相关文章:

SpringSecurity高级用法

SpringSecurity的高级用法&#xff0c;包括自定义loginUrl携带参数&#xff0c;自定义认证校验逻辑&#xff0c;自定义权限校验逻辑。 示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-advanced-security 一、概述 在项目实际开发过程中&#xff0c;Spr…...

NLP_[2]-认识文本预处理

文章目录 1 认识文本预处理1 文本预处理及其作用2. 文本预处理中包含的主要环节2.1 文本处理的基本方法2.2 文本张量表示方法2.3 文本语料的数据分析2.4 文本特征处理2.5数据增强方法2.6 重要说明 2 文本处理的基本方法1. 什么是分词2 什么是命名实体识别3 什么是词性标注 1 认…...

字符设备驱动开发

驱动就是获取外设、传感器数据和控制外设。数据会提交给应用程序。 Linux 驱动编译既要编写一个驱动&#xff0c;还要编写一个简单的测试应用程序。 而单片机下驱动和应用都是放在一个文件里&#xff0c;也就是杂在一块。而 Linux 则是分开了。 一、字符设备驱动开发流程 Lin…...

c语言:取绝对值

假设我们有一个 long 类型的变量 l&#xff0c;我们希望恢复其绝对值。以下是两种方法的对比&#xff1a; 方法1&#xff1a;使用条件语句 这个很好理解&#xff0c;负数时取负运算 &#xff0c;用于数值的符号反转。 long abs_value(long l) {if (l < 0) {return -l;} e…...

DeepSeek从入门到精通教程PDF清华大学出版

DeepSeek爆火以来&#xff0c;各种应用方式层出不穷&#xff0c;对于很多人来说&#xff0c;还是特别模糊&#xff0c;有种雾里看花水中望月的感觉。 最近&#xff0c;清华大学新闻与传播学院新媒体研究中心&#xff0c;推出了一篇DeepSeek的使用教程&#xff0c;从最基础的是…...

HTML之CSS定位、浮动、盒子模型

HTML之CSS定位、浮动、盒子模型 定位 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document<…...

LQB(1)-python-各种基础排序

前言 除了内置的快速排序sort()&#xff0c;python也可以实现冒泡排序、选择排序、插入排序、快速排序、归并排序和桶排序。 一、冒泡排序 (Bubble Sort) 基础代码 def bubble_sort(arr):n len(arr)for i in range(n):swapped False # 优化&#xff1a;若本轮无交换则提前…...

解锁国内主流前端与后端框架

前端框架大揭秘 在当今的 Web 开发领域&#xff0c;前端框架的地位愈发举足轻重。随着用户对 Web 应用交互性和体验性要求的不断攀升&#xff0c;前端开发不再仅仅是简单的页面布局与样式设计&#xff0c;更需要构建复杂且高效的用户界面。前端框架就像是一位得力助手&#xf…...

使用OBS推流,srs服务器播放

说明&#xff1a; ffmpeg可以推流&#xff0c;但是是命令行方式不太友好&#xff0c;还可以使用主流的OBS开源推流软件&#xff0c;可从官网Open Broadcaster Software | OBS 下载最新版本&#xff0c;目前很多网络主播都是用它做直播。该软件支持本地视频文件以及摄像头推流。…...

【鸿蒙HarmonyOS Next实战开发】多媒体视频播放-ijkplayer

简介 ijkplayer是OpenHarmony和HarmonyOS环境下可用的一款基于FFmpeg的视频播放器。 演示 下载安装 ohpm install ohos/ijkplayer使用说明 import { IjkMediaPlayer } from "ohos/ijkplayer";import type { OnPreparedListener } from "ohos/ijkplayer";i…...

GRU 和 LSTM 公式推导与矩阵变换过程图解

GRU 和 LSTM 公式推导与矩阵变换过程图解 GRULSTM 本文的前置篇链接: 单向/双向&#xff0c;单层/多层RNN输入输出维度问题一次性解决 GRU GRU&#xff08;Gate Recurrent Unit&#xff09;是循环神经网络&#xff08;RNN&#xff09;的一种&#xff0c;可以解决RNN中不能长期…...

现在中国三大运营商各自使用的哪些band频段

现在中国三大运营商4G和5G频段分配情况&#xff1a; 中国移动 4G频段&#xff1a; TD-LTE&#xff1a; Band 39&#xff1a;1880-1920MHz&#xff0c;实际使用1885-1915MHz。 Band 40&#xff1a;2300-2400MHz&#xff0c;实际使用2320-2370MHz。 Band 41&#xff1a;2515-26…...

使用Jenkins实现鸿蒙HAR应用的自动化构建打包

使用Jenkins实现鸿蒙HAR应用的自动化构建打包 在软件开发领域&#xff0c;自动化构建是提高开发效率和确保代码质量的重要手段。特别是在鸿蒙&#xff08;OpenHarmony&#xff09;应用开发中&#xff0c;自动化构建更是不可或缺。本文将详细介绍如何使用Jenkins命令行工具实现…...

AI时代,职场人如何开启学习之旅

为什么要学习 AI 在当今数字化时代&#xff0c;AI 正以前所未有的速度改变着我们的工作和生活方式。从智能客服到自动化生产&#xff0c;从数据分析到个性化推荐&#xff0c;AI 已经广泛渗透到各个行业和领域。学习 AI&#xff0c;对于工作人员来说&#xff0c;不仅是提升工作…...

MIT6.824 Lecture 2-RPC and Threads Lecture 3-GFS

Lecture 2-RPC and Threads Go语言在多线程、同步&#xff0c;还有很好用的RPC包 《Effective Go》 线程是实现并发的重要工具 在分布式系统里关注多线程的原因&#xff1a; I/O concurrencyParallelismConvenience Thread challenges 用锁解决race问题 Coordination channel…...

MySQL第五次作业

根据图片内容完成作业 1.建表 &#xff08;1&#xff09;建立两个表:goods(商品表)、orders(订单表) mysql> create table goods( -> gid char(8) primary key, -> name varchar(10), -> price decimal(8,2), -> num int); mysql> create t…...

【PDF提取内容】如何批量提取PDF里面的文字内容,把内容到处表格或者批量给PDF文件改名,基于C++的实现方案和步骤

以下分别介绍基于 C 批量提取 PDF 里文字内容并导出到表格&#xff0c;以及批量给 PDF 文件改名的实现方案、步骤和应用场景。 批量提取 PDF 文字内容并导出到表格 应用场景 文档数据整理&#xff1a;在处理大量学术论文、报告等 PDF 文档时&#xff0c;需要提取其中的关键信…...

智慧机房解决方案(文末联系,领取整套资料,可做论文)

智慧机房解决方案-软件部分 一、方案概述 本智慧机房解决方案旨在通过硬件设备与软件系统的深度整合&#xff0c;实现机房的智能化管理与服务&#xff0c;提升机房管理人员的工作效率&#xff0c;优化机房运营效率&#xff0c;确保机房设备的安全稳定运行。软件部分包括机房管…...

【C编程问题集中营】使用数组指针时容易踩得坑

【C编程问题集中营】使用数组指针时容易踩得坑 文章目录 【C编程问题集中营】使用数组指针时容易踩得坑一、获取数组首地址二、应用场景举例2.1 正常场景2.2 异常场景 三、总结 一、获取数组首地址 一维数组的首地址即数组第一个元素的指针&#xff0c;常用的获取一维数组首地…...

【Redis】Linux、Windows、Docker 环境下部署 Redis

一、Linux环境部署Redis 1、卸载 # 查看 Redis 是否还在运行 [appuserlocalhost redis]$ ps -ef|grep redis appuser 135694 125912 0 14:24 pts/1 00:00:00 ./bin/redis-server *:6379 appuser 135731 125912 0 14:24 pts/1 00:00:00 grep --colorauto redis# 停止…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...