sudo su su_Spring Security应用程序中的su和sudo

sudo su su

很久以前,我从事的项目具有很强大的功能。 有两个角色:用户和主管。 主管可以以任何方式更改系统中的任何文档,而用户则更受工作流约束的限制。 当普通用户对当前正在编辑并存储在HTTP会话中的文档有疑问时,主管可以介入,切换到特殊的主管模式并绕过所有约束。 完全自由。 同一台计算机,同一键盘,同一HTTP会话。 通过输入秘密密码,只有管理员可以设置的特殊标志。 主管完成后,他或她可以清除该标志并再次启用常规约束。

此功能运行良好,但实施效果不佳。 每个单个输入字段的可用性取决于该超级用户模式标志。 使用isSupervisorMode()检查在数十个地方污染了业务方法。 请记住,如果管理员只是使用普通凭据登录,则此模式是隐式的,因此安全约束基本上是重复的。

当我们的应用程序可以高度自定义并具有大量安全角色时,就会出现另一个有趣的用例。 迟早您将面临异常(正常, 错误 ),您无法复制具有不同权限的异常。 能够以该特定用户身份登录并环顾四周可能是一个很大的胜利。 当然,您不知道用户的密码( 不是吗? )。 类似UNIX的系统找到了解决此问题的方法: su切换用户 )和sudo命令。 出乎意料的是, Spring Security附带了内置的SwitchUserFilter ,它在原则上模仿Web应用程序中的su 。 试一试吧!

您只需要声明自定义过滤器:

<bean id="switchUserProcessingFilter"class="org.springframework.security.web.authentication.switchuser.SwitchUserFilter"><property name="userDetailsService" ref="userDetailsService"/><property name="targetUrl" value="/"/>
</b:bean>

并在<http>配置中指向它:

<http auto-config="true" use-expressions="true"><custom-filter position="SWITCH_USER_FILTER" ref="switchUserProcessingFilter" /><intercept-url pattern="/j_spring_security_switch_user" access="hasRole('ROLE_SUPERVISOR')"/>...

而已! 请注意,我保护了/j_spring_security_switch_user URL模式。 您猜对了,这就是您以其他用户身份登录的方式,因此我们希望此资源得到良好的保护。 默认情况下,使用j_username参数名。 将上述更改应用于您的Web应用程序并以具有ROLE_SUPERVISOR的用户ROLE_SUPERVISOR登录后,可以简单地浏览至:

/j_spring_security_switch_user?j_username=bob

假设存在这样的用户,您将自动以bob身份登录。 此处不需要密码。 模拟完他后,浏览到/j_spring_security_exit_user将恢复您以前的凭据。 当然,所有这些URL是可配置的。 参考文档中未记录SwitchUserFilter ,但谨慎使用时它是非常有用的工具。

确实具有强大的力量…… 。 像任何其他任意用户一样,甚至让最受信任的用户登录也具有很大的风险。 想象一下在Facebook上的这种功能,这是不可能的! ( 很好…… )因此,跟踪和审核成为一项主要要求。

我通常首先要做的是在Spring Security过滤器之后添加一个小的servlet过滤器,该过滤器将用户名添加到MDC :

import org.slf4j.MDC;public class UserNameFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();final String userName = authentication.getName();final String fullName = userName + (realName != null ? " (" + realName + ")" : "");MDC.put("user", fullName);try {chain.doFilter(request, response);} finally {MDC.remove("user");}}private String findSwitchedUser(Authentication authentication) {for (GrantedAuthority auth : authentication.getAuthorities()) {if (auth instanceof SwitchUserGrantedAuthority) {return ((SwitchUserGrantedAuthority)auth).getSource().getName();}}return null;}//...
}

只要记住 Spring Security 之后将其添加到web.xml 。 此时,您可以在logback.xml引用"user"键:

<pattern>%d{HH:mm:ss.SSS} | %-5level | %X{user} | %thread | %logger{1} | %m%n%rEx</pattern>

看到%X{user}代码段? 每次登录的用户在系统中执行某些触发日志语句的操作时,都会看到该用户的名称:

21:56:55.074 | DEBUG | alice | http-bio-8080-exec-9 | ...
//...
21:56:57.314 | DEBUG | bob (alice) | http-bio-8080-exec-3 | ...

第二个日志语句很有趣。 如果您看一下上面的findSwitchedUser()调用,很明显,作为管理员的alice切换到用户bob ,现在代表他浏览。

有时您需要更强大的审核系统。 幸运的是,Spring框架具有内置的事件基础结构,我们可以利用在有人切换用户并退出此模式时发送的AuthenticationSwitchUserEvent优势:

@Service
public class SwitchUserListenerimplements ApplicationListener<AuthenticationSwitchUserEvent> {private static final Logger log = LoggerFactory.getLogger(SwitchUserListener.class);@Overridepublic void onApplicationEvent(AuthenticationSwitchUserEvent event) {log.info("User switch from {} to {}",event.getAuthentication().getName(),event.getTargetUser().getUsername());}
}

当然,您可以使用所需的任何业务逻辑来替换简单的日志记录,例如,将此类事件存储在数据库中或向安全员发送电子邮件。

因此,我们知道如何以其他用户身份登录一段时间,然后退出这种模式。 但是,如果我们需要“ sudo ”,即代表其他用户仅发出一个HTTP请求,该怎么办? 当然,我们可以切换到该用户,运行该请求,然后退出。 但这似乎太繁琐且麻烦。 当客户端程序访问我们的API并希望以其他用户身份查看数据时(考虑测试复杂的ACL),可能会弹出这样的要求。

添加自定义HTTP标头以表示这样的特殊模拟请求听起来很合理。 假设客户端已经在进行身份验证(例如使用JSESSIONID cookie),则它仅在一个请求期间有效。 不幸的是,Spring Security不支持此功能,但是很容易在SwitchUserFilter之上SwitchUserFilter

public class SwitchUserOnceFilter extends SwitchUserFilter {@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;final String switchUserHeader = request.getHeader("X-Switch-User-Once");if (switchUserHeader != null) {trySwitchingUserForThisRequest(chain, request, res, switchUserHeader);} else {super.doFilter(req, res, chain);}}private void trySwitchingUserForThisRequest(FilterChain chain, HttpServletRequest request, ServletResponse response, String switchUserHeader) throws IOException, ServletException {try {proceedWithSwitchedUser(chain, request, response, switchUserHeader);} catch (AuthenticationException e) {throw Throwables.propagate(e);}}private void proceedWithSwitchedUser(FilterChain chain, HttpServletRequest request, ServletResponse response, String switchUserHeader) throws IOException, ServletException {final Authentication targetUser = attemptSwitchUser(new SwitchUserRequest(request, switchUserHeader));SecurityContextHolder.getContext().setAuthentication(targetUser);try {chain.doFilter(request, response);} finally {final Authentication originalUser = attemptExitUser(request);SecurityContextHolder.getContext().setAuthentication(originalUser);}}}

与原始SwitchUserFilter的唯一区别是,如果存在"X-Switch-User-Once" ,我们将凭据切换到由此标头的值表示的用户-但是仅在一个HTTP请求期间。 SwitchUserFilter假定要切换到的用户名在j_username参数下,因此我不得不使用SwitchUserRequest包装器作弊:

private class SwitchUserRequest extends HttpServletRequestWrapper {private final String switchUserHeader;public SwitchUserRequest(HttpServletRequest request, String switchUserHeader) {super(request);this.switchUserHeader = switchUserHeader;}@Overridepublic String getParameter(String name) {switch (name) {case SPRING_SECURITY_SWITCH_USERNAME_KEY:return switchUserHeader;default:return super.getParameter(name);}}
}

我们的自定义“ sudo ”就位了! 您可以使用curl进行测试:

$ curl localhost:8080/books/rest/book \-H "X-Switch-User-Once: bob" \-b "JSESSIONID=..."

当然,如果没有JSESSIONID cookie,系统将不允许我们进入。我们必须首先登录,并具有访问sudo功能的特殊特权。 切换用户是一个方便且功能强大的工具。 如果您想在实践中尝试,请在GitHub上查看工作示例 。

参考: Java和社区博客中JCG合作伙伴 Tomasz Nurkiewicz提供的Spring Security应用程序中的su和sudo 。

翻译自: https://www.javacodegeeks.com/2013/07/su-and-sudo-in-spring-security-applications.html

sudo su su

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

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

相关文章

linux如何判断同名进程个数,Linux下判断是否存在多个同名进程

Linux 下如何判断同名进程的个数&#xff0c;这个可以通过shell命令ps -e | grep -c "所查进程名字"&#xff0c;就可以得到进程的个数。这里给出代码实现。bool processNumber(char *name){FILE *fptr;bool bret false;char cmd[255] {\0};char buf[255] {\0};sp…

having和where可以同时使用吗_阴、阳离子聚丙烯酰胺可以同时混合溶解使用吗?...

聚丙烯酰胺是一种水处理药剂&#xff0c;需要溶解在水中制成浓度为0.1%-0.5%的聚丙烯酰胺水溶液。一般来说&#xff0c;当聚丙烯酰胺实际使用时&#xff0c;阴离子聚丙烯酰胺和阳离子聚丙烯酰胺可以同时使用。但是&#xff0c;阳离子聚丙烯酰胺和阴离子聚丙烯酰胺不能混合在一起…

Lombok,AutoValue和Immutables,或如何编写更少,更好的代码返回

在上一篇有关Lombok库的文章中 &#xff0c;我描述了一个库&#xff0c;该库有助于处理Java中的样板代码&#xff08; 是的&#xff0c;我知道这些问题已经在Kotlin中解决了 &#xff0c;但这是现实生活&#xff0c;我们不能一味地坐下来&#xff0c;一旦出现较新或更简单的语言…

noj大作业c语言扫雷,noj大作业.doc

作业名称&#xff1a;算法演示程序学 院&#xff1a;航海学院班 级&#xff1a;学 号&#xff1a;2013300951姓 名&#xff1a;苏和团队组成&#xff1a;西北工业大学2015年11月11日1、问题与背景(描述程序所要解决的问题或应用背景)C语言经过几十年的发展已经发展出多种多样的…

福州PHP讲师招聘_“艺”起就业|招聘信息汇总

亲爱的美术学院毕业生们在全国上下万众一心抗击新冠肺炎疫情的关键时期学院党委高度重视并时刻关注着每一位毕业生的就业工作为进一步做好疫情防控工作也为进一步确保同学们顺利求职就业保障毕业生就业工作的时效性学院公众号特别设立“艺”起就业—招聘信息发布栏目 由院学工…

哪个app最费电_关于石墨烯养生地暖,业主最关心的几大问题,答案附上!

很多人对石墨烯地暖有些许误解&#xff0c;不敢轻易接受。其实不然&#xff0c;石墨烯地暖是一种供热效果好、安全性高、运用寿命长、节能环保的新型健康采暖方式&#xff0c;不仅适用于住宅小区、别墅等家庭采暖&#xff0c;也可用于办公楼、医院等各类公共建筑采暖。在众多对…

双机之间的串行通信设计 c语言编程,双机串行通信设计精品.doc-资源下载人人文库网...

双机串行通信设计 精品.doc所属课程名称 单片机原理与接口技术 题 目 双机串行通信 二 总体设计2.1 设计目的 通过本次课题设计&#xff0c;应用单片机原理及其接口技术等所学相关知识及查阅资料&#xff0c;完成简易双机串行通信设计&#xff0c;以达到理论与实践更好的结合、…

cpu 抖动_微抖动,繁忙的等待和绑定CPU

cpu 抖动性能分析新机器 当我在新机器上工作时&#xff0c;我想了解它的局限性。 在这篇文章中&#xff0c;我将研究机器的抖动以及忙于等待本周末构建的新PC的影响。 该机器的规格很有趣&#xff0c;但不是发布目的。 永远不要少于它们&#xff1a; i7-3970X六核运行于4.5 GH…

南京邮电大学通达学院c语言实验报告,南京邮电大学通达学院c语言程序报告.docx...

南京邮电大学通达学院c语言程序报告南京邮电大学通达学院程序设计(上机)报告题 目&#xff1a; R015M P008E专 业 学 生 姓 名 班 级 学 号 指 导 教 师 日 期 2015年5月评 分 细 则评分项优秀良好中等及格不及格遵守机房规章制度上机表现学习态度基础知识水平程序设计能力课题…

两端分散对齐怎么设置_Word文字很难对齐?用这4个方法,2秒可对齐所有文字!...

日常工作中&#xff0c;我们在给Word文档进行对齐操作的时候&#xff0c;很多人都是猛敲空格键来对齐文字&#xff0c;通常是一顿操作猛如虎&#xff0c;仔细一看原地杵。简单的文字对齐&#xff0c;这种方法可能还算凑效&#xff0c;但稍显复杂的就不那么管用了。今天叨叨君就…

怎样学c++程序语言,如何学好 C++——学习门槛最高的编程语言

根据InfoQ 编程语言 2 月排行榜&#xff0c;统计发现&#xff0c;学习门槛最高的编程语言是 C。那么如何学好这门又难、门槛又高的语言呢&#xff1f;前面我们介绍过C。C是一种面向对象的计算机程序设计语言&#xff0c;由美国AT&T贝尔实验室的本贾尼斯特劳斯特卢普博士在2…

首个JDK 10(18.3)发行候选版(内部版本43)展示了新的版本控制方案

Mark Reinhold的帖子“ JDK 10&#xff1a;First Release Candidate ”宣布“内部版本43中没有未解决的P1错误”&#xff0c;并将Build 43命名为最初的JDK 10版本候选 。 Reinhold帖子还指向“ JDK 10 Early Access Builds ”页面&#xff0c;该页面包含发行说明的链接。 到基于…

7 centos 查看程序文件数量_CentOS之使用Systemd添加自定义系统服务

文章引言Systemd 就是为了解决Linux 的启动一直采用init进程问题而诞生的。它的设计目标是&#xff0c;为系统的启动和管理提供一套完整的解决方案。根据 Linux 惯例&#xff0c;字母d是守护进程&#xff08;daemon&#xff09;的缩写。 Systemd 这个名字的含义&#xff0c;就是…

做完c语言通讯录系统后的小结,c语言通讯录管理系统的总结

c语言通讯录管理系统的总结c语言通讯录管理系统的总结c语言课设管理系统总结完成情况防暴力输入密码加密输入并删除管理员和用户端两个端管理员对用户的账号删除注册用户用户的账户名及密码修改用户基本操作管理员基本操作存在的问题管理员无法对用户的数据进行修改未使用链表由…

因特尔显卡自定义分辨率_电脑显示器分辨率超频教程:1080P超2K分辨率的方法...

我们玩过CPU超频、显卡超频、内存超频等&#xff0c;相信不少用户还没有尝试过显示器超频&#xff0c;其实在前段时间&#xff0c;装机之家为广大爱好者发布了一篇【电脑显示器刷新率怎么超频&#xff1f;电脑显示器提高屏幕刷新率超频教程】文章&#xff0c;我们将一款普通60H…

pyinstaller安装失败解决

1.看到直接输入pip install pyinstaller 似乎很简单 2.尝试结果失败 3.其实失败有很多原因&#xff0c;但是有一个自我感觉通用的办法&#xff1a; 使用管理员身份打开cmd 输入 python -m pip install --upgrade pip 输入 pip install pywin32 输入 pip install wheel 输入 pip…

android pdu 编码规则,[转载]PDU编码规则

目前&#xff0c;发送短消息常用Text和PDU(Protocol DataUnit&#xff0c;协议数据单元)模式。使用Text模式收发短信代码简单&#xff0c;实现起来十分容易&#xff0c;但最大的缺点是不能收发中文短信&#xff1b;而PDU模式不仅支持中文短信&#xff0c;也能发送英文短信。PDU…

Java 9示例–收集的工厂方法–创建不可修改的列表,集合和映射

大家好&#xff0c;这是我在该博客上发表的有关Java 9功能的第一篇文章&#xff0c;今天您将了解我最喜欢的功能“收集的工厂方法” &#xff0c;它是JEP 269的一部分。JEP代表JDK增强建议。 如果您曾经在Groovy或Kotlin工作过&#xff0c;那么您就会知道使用集合文字使用元素创…

郴州郴锦机器人_减税降费宣传走进郴州市民营企业高质量发展专题培训班

红网时刻郴州8月23日讯(通讯员 陈磊 记者 欧群军)“毫不动摇支持民营经济健康发展离不开税收政策的有力支持。近年来&#xff0c;特别是今年以来国家系列税收优惠政策的出台&#xff0c;为民营经济的发展注入了新的活力。”8月22日&#xff0c;郴州市税务局减税降费宣讲课堂走进…

FPGA(8)--频率计检测控制系统

文章目录一、设计要求1.整体控制系统设计要求2.频率计检测设计要求二、设计思路1.确定VHDL描述与原理图相结合完成设计2.确定状态情况3.数码管显示功能三、设计内容1. 频率检测部分VHDL描述2. 七段数码管显示部分VHDL描述3. 系统主控制部分VHDL描述4.将三个部分的VHDL描述分别都…