我的公司一直在判断Spring MVC,以确定我们是否应该在下一个项目中使用它.到目前为止,我喜欢我所看到的,现在我正在查看Spring安全模块,以确定它是否是我们可以/应该使用的东西.

我们的安全要求非常基本;用户只需要提供用户名和密码就可以访问网站的某些部分(例如获取有关其帐户的信息);网站上有一些页面(常见问题解答、支持等),匿名用户可以访问这些页面.

在我创建的原型中,我在会话中为经过身份验证的用户存储了一个"LoginCredentials"对象(它只包含用户名和密码);例如,一些控制器判断该对象是否在会话中,以获得对登录用户名的引用.我希望用Spring Security来替代这种自成体系的逻辑,这样做的好处是消除了"我们如何跟踪登录的用户?"这样做的好处是消除了任何类型的"我们如何跟踪登录的用户?"以及"我们如何对用户进行身份验证?"从我的控制器/业务代码.

Spring Security似乎提供了一个(每个线程)"上下文"对象,以便能够从应用程序中的任何位置访问用户名/主体信息……

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

... 在某种程度上,这看起来很不像Spring,因为这个对象是一个(全局)单态.

我的问题是:如果这是在Spring Security中访问经过身份验证的用户信息的标准方法,那么在单元测试需要经过身份验证的用户时,向SecurityContext中注入身份验证对象以使其可用于我的单元测试的公认方法是什么?

我需要在每个测试用例的初始化方法中连接这一点吗?

protected void setUp() throws Exception {
    ...
    SecurityContextHolder.getContext().setAuthentication(
        new UsernamePasswordAuthenticationToken(testUser.getLogin(), testUser.getPassword()));
    ...
}

这似乎过于冗长.有没有更简单的方法?

SecurityContextHolder号物体本身看起来很不像弹簧……

推荐答案

问题在于Spring Security不能使身份验证对象在容器中作为bean使用,因此无法轻松地注入或自动连接它.

在开始使用Spring安全性之前,我们将在容器中创建一个会话范围的bean来存储主体,将其注入"AuthenticationService"(singleton),然后将该bean注入需要了解当前主体的其他服务.

如果您正在实现您自己的身份验证服务,您基本上可以做同样的事情:创建一个具有"主体"属性的会话作用域bean,将其注入到您的身份验证服务中,让auth服务在身份验证成功时设置该属性,然后在需要时使auth服务可供其他bean使用.

如果使用SecurityContextHolder,我不会觉得太糟糕.虽然我知道它是静态/单例的,Spring不鼓励使用这些东西,但它们的实现会根据环境的不同而采取适当的行为:Servlet容器中的会话范围,JUnit测试中的线程范围,等.单例的真正限制因素是,它提供的实现对不同的环境缺乏灵活性.

Java相关问答推荐

OpenRewriter-如何替换连锁/流畅方法调用中的方法?

验证使用GCP生成的非对称密钥时签名不起作用

Kotlin ReadWriteProperty:无法使用T作为具体化类型参数.改为使用类

如何使用CSS为选定但未聚焦的表格行设置背景 colored颜色 ?

RxJava PublishSubject缓冲区元素超时

Junit with Mockito for java

嵌入式ActiveMQ Artemis Web控制台加载错误

如何使用Maven和Spring Boot将构建时初始化、跟踪类初始化正确传递到本机编译

Spark上下文在向Spark提交数据集时具有内容,但Spark在实际构建它时发现它为空

Helidon 4和Http API

无法在Java中处理PayPal支付响应

如何在JavaFX循环中完美地制作一个AudioClip/MediaPlayer?

Quarkus:运行时出现EnumConstantNotPresentException

Java在操作多个属性和锁定锁对象时使用同步和易失性

无法使用Java PreparedStatement在SQLite中的日期之间获取结果

在Oracle中调用输出参数在索引处缺少IN或OUT参数的函数

如何使用jooq更新记录?

为什么我的登录终结点不能被任何请求访问?

基于距离的APACHE POI公式判断

";home/runner/work/中没有文件...匹配到[**/pom.xml];Maven项目的构建过程中出现错误