[英]NullPointerException at org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.<init>
Small question on testing the configure
method of WebSecurityConfigurerAdapter
please.请测试
WebSecurityConfigurerAdapter
的configure
方法的小问题。
I am using Spring Boot 2.6.3, and therefore spring-boot-starter-security 2.6.3 (question applicable to Spring 2.x.x+)我正在使用 Spring Boot 2.6.3,因此使用 spring-boot-starter-security 2.6.3(适用于 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.我只想编写适当的测试,例如测试路由,如 /health /badhealth /intances /foo 等。
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.不幸的是,在有机会测试路线之前,我总是得到 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)
I am having a hard time understand the reason of this NPE, what is null, and how to properly test this.我很难理解这个 NPE 的原因,null 是什么,以及如何正确测试它。
Should I set something up in particular that I missed?我应该特别设置一些我错过的东西吗? Maybe some Mock that I am not leveraging?
也许是我没有利用的一些 Mock?
Finally, is there a way to test this statically, without having to spin up the server itself?最后,有没有办法静态测试这个,而不必启动服务器本身?
Thank you谢谢
The old (spring-security-config-5.5.5, for example) ExpressionUrlAuthorizationConfigurer
constructor looked like this旧的(例如 spring-security-config-5.5.5)
ExpressionUrlAuthorizationConfigurer
构造函数看起来像这样
public ExpressionUrlAuthorizationConfigurer(ApplicationContext context) {
this.REGISTRY = new ExpressionInterceptUrlRegistry(context);
}
the new one (spring-security-config-5.6.2) now has context.getBeanNamesForType(...
新的 (spring-security-config-5.6.2) 现在有
context.getBeanNamesForType(...
public ExpressionUrlAuthorizationConfigurer(ApplicationContext context) {
String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
if (grantedAuthorityDefaultsBeanNames.length == 1) {
GrantedAuthorityDefaults grantedAuthorityDefaults = context.getBean(grantedAuthorityDefaultsBeanNames[0],
GrantedAuthorityDefaults.class);
this.rolePrefix = grantedAuthorityDefaults.getRolePrefix();
}
else {
this.rolePrefix = "ROLE_";
}
this.REGISTRY = new ExpressionInterceptUrlRegistry(context);
}
Since the application context hasn't been started, context
is null and you get the NPE.由于应用程序上下文尚未启动,
context
为 null,您将获得 NPE。 Before, it didn't matter that the test didn't have an ApplicationContext, now it does.以前,测试没有 ApplicationContext 并不重要,现在有。 I believe you will have to initiate the context for the tests to pass: https://spring.io/guides/gs/testing-web/
我相信您必须启动测试通过的上下文: https://spring.io/guides/gs/testing-web/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.