Spring Security中的SecurityContext和SecurityContextHolder是什么?

SecurityContextSecurityContextHolder是Spring Security的两个基本类。 SecurityContext用于存储当前经过身份验证的用户的详细信息,也称为原理。 因此,如果必须获取用户名或任何其他用户详细信息,则需要首先获取此SecurityContextSecurityContextHolder是一个帮助程序类,它提供对安全上下文的访问。 默认情况下,它使用ThreadLocal对象存储安全性上下文,这意味着即使不传递SecurityContext对象,该安全性上下文也始终可用于同一执行线程中的方法。 不过,不必担心Web应用程序中的ThreadLocal内存泄漏 ,Spring Security会负责清理ThreadLocal。

顺便说一句,这不是SecurityContextHolder可以存储当前SecurityContext的唯一方法,可以在启动时为其配置策略,以指定如何存储上下文。 例如,可以将SecurityContextHolder.MODE_GLOBAL策略用于独立的应用程序。

要学习的关键是, 如何从SecurityContextHolder获得SecurityContext? 然后从中检索当前的用户详细信息? 例如,如果您想知道当前登录用户的用户名,那么如何在Spring security中获得该用户名?

为了获取当前的用户名,首先需要一个SecurityContext ,它是从SecurityContextHolder获得的。 此SecurityContext将用户详细信息保留在Authentication对象中,该对象可以通过调用getAuthentication()方法获得。

一旦获得身份验证对象,就可以转换为UserDetails或按原样使用它。 UserDetails对象是Spring Security用于保留用户相关信息的对象。

如何在Spring Security中获取当前的登录用户名

这是获取Spring安全性中的安全性上下文并获取当前登录用户的名称的代码:

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();if (principal instanceof UserDetails) {String username = ((UserDetails)principal).getUsername();
} else {String username = principal.toString();
}

getContext()返回的对象是SecurityContext接口的实例。 这是存储在线程本地存储中的对象。

getPrincipal()方法通常在Spring Security中返回UserDetails对象,该对象包含当前登录用户的所有详细信息。

无论如何,如果您仔细观察,您会发现在考虑Spring和依赖注入时,这并不是一个很好的代码。 因此,如果您需要了解当前登录的用户详细信息(例如在Spring MVC控制器中),建议您声明一个依赖项,然后让Spring为您提供Principal对象,而不是查询它们并创建一个紧密耦合的系统。

这是一个例子

import java.security.Principal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class MVCController {@RequestMapping(value = "/username", method = RequestMethod.GET)@ResponseBodypublic String currentUserName(Principal principal) {return principal.getName();}}

另外,您也可以要求提供Authentication对象而不是Principal对象,如下所示:

import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class SpringMVCController {@RequestMapping(value = "/username", method = RequestMethod.GET)@ResponseBodypublic String currentUserName(Authentication authentication) {return authentication.getName();}
}

如果您想了解更多方法,还可以参阅我的文章有关在Spring Security中获取当前用户名的3种方法 ,在此我讨论了几种在Spring MVC控制器中获取当前用户名的更多方法。

这就是Spring安全性中的安全性上下文,以及如何从SecurityContextHolder类获取SecurityContext的全部内容。 这些是一些基本类,因此您必须熟悉它们。

存储部分(即SecurityContext存储在ThreadLocal是可选的,但最好了解详细信息。 请记住,如果您需要用户详细信息(例如用户名等),则最好在Spring MVC控制器中请求Principal或Authentication对象,而不要使用SecurityContextHolder来获取它们。

感谢您到目前为止阅读本文。 如果您喜欢此Spring Security教程,请与您的朋友和同事分享。 如果您有任何疑问或反馈,请留言。

翻译自: https://www.javacodegeeks.com/2018/02/securitycontext-securitycontextholder-spring-security.html

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

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

相关文章

codemirror java代码_codemirror使用(示例代码)

JS使用使用bower下载javascript bower i codemirror引入样式文件html 引入js文件html 文档结构html 初始化javascript // mode: "text/javascript", // mode: "text/css" window.onload function(){ var myCodeMirror CodeMirror.fromTextArea(document.…

(3.5)HarmonyOS鸿蒙上下左右方向滑动

需要获取按下时候的坐标和松开时候的坐标,并将两者进行比较。 ①MainAbilitySlice.java文件 可以根据使用情况做修改代码中判断处的限制偏差范围。 package com.example.yeman.slice;import com.example.yeman.ResourceTable; import ohos.aafwk.ability.Ability…

java selenium用js点击_Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?...

小编典典你可以通过以下任一过程解决它们:1.由于存在JavaScript或AJAX调用而无法单击元素尝试使用ActionsClass:WebElement element driver.findElement(By.id("navigationPageButton"));Actions actions new Actions(driver);actions.moveT…

(3.5)HarmonyOS鸿蒙多按钮点击事件

多按钮的点击事件其实与只有一个是类似的,只不过要在调用 onClick()时进行判断,判断获取到的component是谁即可。 package com.example.yeman.slice;import com.example.yeman.ResourceTable; import ohos.aafwk.ability.Ability…

sql 注射_基本注射/资格赛,范围

sql 注射这是上周解决的DI / CDI基础知识的延续-在本文中,我将讨论基础注入,限定词和范围。 在上一个主题中,我们提供了有关DI / CDI概念的大量信息,我们还讨论了如何使用注释加载这些bean或类-这构成了对象的组成并创建了关于如…

计算机二级web题目(9.1)--综合选择题3

前些天发现了一个巨牛的人工智能学习电子书,通俗易懂,风趣幽默,无广告,忍不住分享一下给大家。(点击跳转人工智能学习资料) 1下列叙述中正确的是(D)。 A、栈是"先进先出"的线性表 B、队列是"…

java小程序 2048_微信小程序之游戏2048

主要用来锻炼逻辑思维能力image.png可以选模式image.png这里面主要解决的问题是:1.判断滑动方向//在滑动块级绑定滑动开始和滑动结束的方法很原始的方法,startFn时保存开始的(x,y),endFn时保存结束的(x1,y2),根据这四个参数 判断方向,算法在方…

现场故事:从Log4J迁移到Log4J2

通过从应用程序中学习企业APM产品,发现更快,更高效的性能监控。 参加AppDynamics APM导览! 与许多Java应用程序一样,AppDynamics Java代理广泛使用日志记录。 多年来,我们一直使用Log4J作为日志记录框架。 虽然Log4J的…

Java面向对象(8)--继承性

多个类中存在相同属性和行为时,可以将这些内容抽取到单独一个类中,那么多个类无需再定义这些相同的属性和行为,只要继承那个类即可。 这里的多个类称为子类(派生类),单独的这个类称为父类(基类或超类)。 语法格式:cla…

aimesh node重启_华硕 RT-AC86U 和 网件 R7000 组 AiMesh 成功

家里之前买了一个 R7000 主路由器,后来我嫌我房间里的信号有点烂( 5G 信号只能 2 格,网速比 2.4G 还慢),所以就入手了一个华硕 RT-AC86U 作为主路由器,R7000 则作为 AP。在买的时候就想组 AiMesh,但是因为种种事情耽搁…

Java面向对象(9)--方法的重写(override/overwrite)

在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类中同名同参数列表的方法。 权限修饰符 返回值类型 方法名(形参列表) throws 异常类型{方法体; }①子类重写的方法…

maven ant_如何在Maven中运行Ant目标?

maven antmaven-antrun-plugin允许我们在各种maven构建阶段中运行ant目标。 我将专门为具有开发环境的开发人员解释maven-antrun-plugin的非常实际的用法。 通常,使用maven build,您会将项目捆绑到war文件或ear文件中。 您可以使用maven-antrun-plugin…

java中打开文件显示_在默认文件资源管理器中打开文件,并使用JavaFX或普通Java突出显示它...

我想做标题所说的.部分解决方案例如,在Windows中,您可以使用以下代码在默认资源管理器中打开文件并突出显示它.(虽然它需要修改包含空格的文件):/*** Opens the file with the System default file explorer.** param path the path*/public static void openFileLo…

win10下vscode配置c语言环境

1、C编译器下载 C编译器(MinGW-W64 GCC)的下载:点击官方下载 或者点击网盘下载提取码为karj 下载完成后解压,将解压后的文件夹放到合适的位置,点开其bin子文件夹,复制路径。 2、win10下环境变量配置 ①…

java jdbc 乱码_【求助】为什么用纯java jdbc插入mysql一直乱码

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼String str "人造革";//gbk编码使用2个字节表示一个汉字,所以buffer的长度应该为6byte[] buffer str.getBytes("gbk");//[-56, -53, -44, -20, -72, -17]System.out.println("gbk编码的byte信息:"…

Java面向对象(10)--super关键字

在子类中使用super来调用父类中的指定操作: ①super可用于访问父类中定义的属性 ②super可用于调用父类中定义的成员方法 ③super可用于在子类构造器中调用父类的构造器 super的追溯不仅限于直接父类。 我们可以在子类的方法或构造器中,通过使用"s…

Java的Gradle依赖关系,使用编译还是实现?

当我向一位同事解释如何将Gradle用于Java项目时(他正在远离Maven ),我们遇到了各种代码示例。 有些示例将编译配置用于依赖项,而其他示例则使用Implements和api 。 dependencies { compile commons-httpclient:commons-httpclien…

Java面向对象(11)--多态性

父类 变量名 new 子类();对象的多态性:父类的引用指向子类的对象 Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明 该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简…

java如何替换字符串0A_我有一个带有“ \ u00a0”的字符串,我需要将其替换为“” str_replace failed...

我需要清理来自各种Microsoft Office套件应用程序(Excel,Access和Word)的字符串(复制/粘贴),每个应用程序都有自己的一组编码。我将json_encode用于调试目的,以便能够看到每个编码的字符。我可以使用str_replace清除到目前为止找到的所有内容…

Java面向对象(12)--对象类型转换 (Casting )

基本数据类型的Casting: ①自动类型转换:小的数据类型可以自动转换成大的数据类型 如long g20; double d12.0f ②强制类型转换:可以把大的数据类型强制转换(casting)成小的数据类型 如 float f(float)12.0; int a(int)1200L Java对象的强制…