org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.处出现 NullPointerException
关于测试 WebSecurityConfigurerAdapter
的 configure
方法的小问题。
我正在使用 Spring Boot 2.6.3,因此 spring-boot-starter-security 2.6.3 (适用于 Spring 2.x.x+ 的问题)
我有自己的安全配置,如下所示:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
@Configuration
public class MySecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
final var httpSecurity = http.authorizeRequests()
.antMatchers("/health")
.permitAll()
.and()
.httpBasic()
.and()
.csrf()
.ignoringAntMatchers("/instances")
.and()
.authorizeRequests();
httpSecurity.anyRequest()
.authenticated()
.and()
.x509()
.subjectPrincipalRegex("CN=(.*?)(?:,|$)")
.userDetailsService(username -> new User(username, "password", AuthorityUtils.commaSeparatedStringToAuthorityList(username)))
.and()
.saml2Login()
.relyingPartyRegistrationRepository(new InMemoryRelyingPartyRegistrationRepository());
}
}
我只想编写适当的测试,例如测试路线,如 /health /badhealth /instances /foo 等。
为了做到这一点,我编写我的单元测试如下:
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import java.util.HashMap;
class MySecurityConfigurationTest {
@DisplayName("Test ALL")
@Test
void testConfigure() {
MySecurityConfiguration mySecurityConfiguration1 = new MySecurityConfiguration();
try {
mySecurityConfiguration1.configure(new HttpSecurity(new ObjectPostProcessor<>() {
@Override
public <O> O postProcess(O object) {
return null;
}
}, new AuthenticationManagerBuilder(new ObjectPostProcessor<>() {
@Override
public <O> O postProcess(O object) {
return null;
}
}), new HashMap<>()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
不幸的是,我总是得到一个 NPE,甚至在有机会测试之前路线。
java.lang.NullPointerException
at org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.<init>(ExpressionUrlAuthorizationConfigurer.java:109)
at org.springframework.security.config.annotation.web.builders.HttpSecurity.authorizeRequests(HttpSecurity.java:1183)
at [...]
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
我很难理解这个 NPE 的原因、什么是 null 以及如何正确测试它。
我应该特别设置一些我错过的东西吗?也许是我没有利用的一些模拟?
最后,有没有一种方法可以静态测试这一点,而无需启动服务器本身?
谢谢
Small question on testing the configure
method of WebSecurityConfigurerAdapter
please.
I am using Spring Boot 2.6.3, and therefore spring-boot-starter-security 2.6.3 (question applicable to Spring 2.x.x+)
I have my own security configuration written as follow:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
@Configuration
public class MySecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
final var httpSecurity = http.authorizeRequests()
.antMatchers("/health")
.permitAll()
.and()
.httpBasic()
.and()
.csrf()
.ignoringAntMatchers("/instances")
.and()
.authorizeRequests();
httpSecurity.anyRequest()
.authenticated()
.and()
.x509()
.subjectPrincipalRegex("CN=(.*?)(?:,|$)")
.userDetailsService(username -> new User(username, "password", AuthorityUtils.commaSeparatedStringToAuthorityList(username)))
.and()
.saml2Login()
.relyingPartyRegistrationRepository(new InMemoryRelyingPartyRegistrationRepository());
}
}
I just want to write appropriate tests, such as testing the routes, like /health /badhealth /intances /foo, etc.
In order to do so, I am writing my unit test as follow:
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import java.util.HashMap;
class MySecurityConfigurationTest {
@DisplayName("Test ALL")
@Test
void testConfigure() {
MySecurityConfiguration mySecurityConfiguration1 = new MySecurityConfiguration();
try {
mySecurityConfiguration1.configure(new HttpSecurity(new ObjectPostProcessor<>() {
@Override
public <O> O postProcess(O object) {
return null;
}
}, new AuthenticationManagerBuilder(new ObjectPostProcessor<>() {
@Override
public <O> O postProcess(O object) {
return null;
}
}), new HashMap<>()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Unfortunately, I am always getting a NPE, before even having the chance to test the routes.
java.lang.NullPointerException
at org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.<init>(ExpressionUrlAuthorizationConfigurer.java:109)
at org.springframework.security.config.annotation.web.builders.HttpSecurity.authorizeRequests(HttpSecurity.java:1183)
at [...]
org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
I am having a hard time understand the reason of this NPE, what is null, and how to properly test this.
Should I set something up in particular that I missed? Maybe some Mock that I am not leveraging?
Finally, is there a way to test this statically, without having to spin up the server itself?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
旧的(例如 spring-security-config-5.5.5)
ExpressionUrlAuthorizationConfigurer
构造函数看起来像这样,新的(spring-security-config-5.6.2)现在有
context.getBeanNamesForType (...
由于应用程序上下文尚未启动,
context
为 null,并且您得到 NPE。以前,测试没有ApplicationContext,现在可以了。我相信您必须启动上下文才能通过测试:https://spring. io/guides/gs/testing-web/
The old (spring-security-config-5.5.5, for example)
ExpressionUrlAuthorizationConfigurer
constructor looked like thisthe new one (spring-security-config-5.6.2) now has
context.getBeanNamesForType(...
Since the application context hasn't been started,
context
is null and you get the NPE. Before, it didn't matter that the test didn't have an ApplicationContext, now it does.I believe you will have to initiate the context for the tests to pass: https://spring.io/guides/gs/testing-web/