Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StackOverFlowError with AuthenticationManager bean #11792

Closed
liqwang opened this issue Sep 8, 2022 · 1 comment
Closed

StackOverFlowError with AuthenticationManager bean #11792

liqwang opened this issue Sep 8, 2022 · 1 comment
Labels
status: waiting-for-triage An issue we've not yet triaged type: bug A general bug

Comments

@liqwang
Copy link

liqwang commented Sep 8, 2022

I'm using Spring Security 5.7.3
The StackOverFlowError occurs with both two conditions:

  • Register an AuthenticationManager bean in SecurityConfig
  • Run the JUnit5 test

The stacktrace of StackOverFlowError is:

"main@1" prio=5 tid=0x1 nid=NA runnable
      StackOverFlowError
      ...
	  at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
	  at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
	  at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
	  at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
	  at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
	  at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:62)
	  at ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:119)
	  at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:419)
	  at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
	  at ch.qos.logback.classic.Logger.log(Logger.java:765)
	  at org.apache.commons.logging.LogAdapter$Slf4jLocationAwareLog.warn(LogAdapter.java:447)
	  at org.springframework.test.context.TestContextManager.logException(TestContextManager.java:550)
	  at org.springframework.test.context.TestContextManager.handleBeforeException(TestContextManager.java:532)
	  at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:296)
	  at org.springframework.test.context.junit.jupiter.SpringExtension.beforeEach(SpringExtension.java:174)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$2(TestMethodTestDescriptor.java:163)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$951/0x0000000800ff54e0.invoke(Unknown Source:-1)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$6(TestMethodTestDescriptor.java:199)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$952/0x0000000800ff56f8.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:199)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:162)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:129)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$260/0x0000000800c99578.accept(Unknown Source:-1)
	  at java.util.ArrayList.forEach(ArrayList.java:1511)
	  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$260/0x0000000800c99578.accept(Unknown Source:-1)
	  at java.util.ArrayList.forEach(ArrayList.java:1511)
	  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	  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$$Lambda$202/0x0000000800c86f60.accept(Unknown Source:-1)
	  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)

Obviously, the error occurs when catching the exception, which is

java.lang.IllegalStateException: Failed to unwrap proxied object

whose stacktrace is:

"main@1" prio=5 tid=0x1 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
	  at org.springframework.test.util.AopTestUtils.getUltimateTargetObject(AopTestUtils.java:97)
	  at org.springframework.boot.test.mock.mockito.SpringBootMockResolver.resolve(SpringBootMockResolver.java:35)
	  at org.mockito.internal.util.MockUtil.resolve(MockUtil.java:118)
	  at org.mockito.internal.util.MockUtil.isMock(MockUtil.java:108)
	  at org.mockito.internal.util.DefaultMockingDetails.isMock(DefaultMockingDetails.java:32)
	  at org.springframework.boot.test.mock.mockito.MockReset.get(MockReset.java:106)
	  at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:82)
	  at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:70)
	  at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.beforeTestMethod(ResetMocksTestExecutionListener.java:57)
	  at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:293)
	  at org.springframework.test.context.junit.jupiter.SpringExtension.beforeEach(SpringExtension.java:174)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$2(TestMethodTestDescriptor.java:163)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$951/0x0000000800ff54e0.invoke(Unknown Source:-1)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$6(TestMethodTestDescriptor.java:199)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$952/0x0000000800ff56f8.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:199)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:162)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:129)
	  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$260/0x0000000800c99578.accept(Unknown Source:-1)
	  at java.util.ArrayList.forEach(ArrayList.java:1511)
	  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$260/0x0000000800c99578.accept(Unknown Source:-1)
	  at java.util.ArrayList.forEach(ArrayList.java:1511)
	  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
	  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	  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$$Lambda$202/0x0000000800c86f60.accept(Unknown Source:-1)
	  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)

The minimum project to cause the bug is here: https://github.com/QuanQuan-CHO/Spring-Security-StackOverFlowError-Example
A very similar question is here: https://stackoverflow.com/questions/67546793/why-is-spring-boot-2-4-5-with-junit5-and-mocked-beans-is-throwing-stackoverflowe

@liqwang liqwang added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Sep 8, 2022
@sjohnr
Copy link
Member

sjohnr commented Sep 9, 2022

Thanks for reaching out, @QuanQuan-CHO!

In your minimal sample, I see an @Bean definition for AuthenticationManager that uses an autowired AuthenticationConfiguration.

I believe I've seen a suggestion similar to this on stackoverflow. What's happening in this case is that a bean cycle is formed between the local AuthenticationManagerBuilder and the parent AuthenticationManager configured by Spring Security. It appears to work because the application runs and can be used, but the cycle is still there as demonstrated by the test.

Generally, I don't think I'd recommend getting an AuthenticationManager in this way, as I believe you will only be able to authenticate using the global configuration (with @Bean UserDetailsService and @Bean PasswordEncoder, etc.) which may not be what you want. However, if this is sufficient for your use case, you can add static to the @Bean method to remove the bean cycle, because the order in which things are built will change and your bean will be declared first. (It looks like this is also what was suggested on the stackoverflow question you mentioned.)

@Configuration
@EnableWebSecurity
public class SecurityConfig{
	@Bean
	public static AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
		return authenticationConfiguration.getAuthenticationManager();
	}
}

I'm going to close this issue for now, as the sample configuration causes a bean cycle. If you feel I've missed anything, let me know and we can re-open if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants