Add SecurityContextHolderStrategy Java Configuration for Defaults
Issue gh-11061
This commit is contained in:
parent
31e25b115e
commit
2c09a300b6
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -24,6 +24,8 @@ import org.springframework.context.ApplicationContextAware;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver;
|
||||
import org.springframework.security.web.method.annotation.CsrfTokenArgumentResolver;
|
||||
import org.springframework.security.web.method.annotation.CurrentSecurityContextArgumentResolver;
|
||||
|
@ -50,11 +52,15 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
|
|||
|
||||
private BeanResolver beanResolver;
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
AuthenticationPrincipalArgumentResolver authenticationPrincipalResolver = new AuthenticationPrincipalArgumentResolver();
|
||||
authenticationPrincipalResolver.setBeanResolver(this.beanResolver);
|
||||
authenticationPrincipalResolver.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
|
||||
argumentResolvers.add(authenticationPrincipalResolver);
|
||||
argumentResolvers
|
||||
.add(new org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver());
|
||||
|
@ -72,6 +78,9 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
|
|||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.beanResolver = new BeanFactoryResolver(applicationContext.getAutowireCapableBeanFactory());
|
||||
if (applicationContext.getBeanNamesForType(SecurityContextHolderStrategy.class).length == 1) {
|
||||
this.securityContextHolderStrategy = applicationContext.getBean(SecurityContextHolderStrategy.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -299,6 +299,7 @@ public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecur
|
|||
.getSecurityContextRepository();
|
||||
this.authFilter.setSecurityContextRepository(securityContextRepository);
|
||||
}
|
||||
this.authFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
F filter = postProcess(this.authFilter);
|
||||
http.addFilter(filter);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,11 +16,14 @@
|
|||
|
||||
package org.springframework.security.config.annotation.web.configurers;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurer;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||
|
||||
/**
|
||||
|
@ -32,6 +35,8 @@ import org.springframework.security.web.DefaultSecurityFilterChain;
|
|||
public abstract class AbstractHttpConfigurer<T extends AbstractHttpConfigurer<T, B>, B extends HttpSecurityBuilder<B>>
|
||||
extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, B> {
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy;
|
||||
|
||||
/**
|
||||
* Disables the {@link AbstractHttpConfigurer} by removing it. After doing so a fresh
|
||||
* version of the configuration can be applied.
|
||||
|
@ -49,4 +54,19 @@ public abstract class AbstractHttpConfigurer<T extends AbstractHttpConfigurer<T,
|
|||
return (T) this;
|
||||
}
|
||||
|
||||
protected SecurityContextHolderStrategy getSecurityContextHolderStrategy() {
|
||||
if (this.securityContextHolderStrategy != null) {
|
||||
return this.securityContextHolderStrategy;
|
||||
}
|
||||
ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
|
||||
String[] names = context.getBeanNamesForType(SecurityContextHolderStrategy.class);
|
||||
if (names.length == 1) {
|
||||
this.securityContextHolderStrategy = context.getBean(SecurityContextHolderStrategy.class);
|
||||
}
|
||||
else {
|
||||
this.securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();
|
||||
}
|
||||
return this.securityContextHolderStrategy;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -146,6 +146,7 @@ public final class AnonymousConfigurer<H extends HttpSecurityBuilder<H>>
|
|||
}
|
||||
if (this.authenticationFilter == null) {
|
||||
this.authenticationFilter = new AnonymousAuthenticationFilter(getKey(), this.principal, this.authorities);
|
||||
this.authenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
}
|
||||
this.authenticationProvider = postProcess(this.authenticationProvider);
|
||||
http.authenticationProvider(this.authenticationProvider);
|
||||
|
|
|
@ -86,6 +86,7 @@ public final class AuthorizeHttpRequestsConfigurer<H extends HttpSecurityBuilder
|
|||
AuthorizationFilter authorizationFilter = new AuthorizationFilter(authorizationManager);
|
||||
authorizationFilter.setAuthorizationEventPublisher(this.publisher);
|
||||
authorizationFilter.setShouldFilterAllDispatcherTypes(this.registry.shouldFilterAllDispatcherTypes);
|
||||
authorizationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
http.addFilter(postProcess(authorizationFilter));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -187,6 +187,7 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>
|
|||
getRequestCache(http));
|
||||
AccessDeniedHandler deniedHandler = getAccessDeniedHandler(http);
|
||||
exceptionTranslationFilter.setAccessDeniedHandler(deniedHandler);
|
||||
exceptionTranslationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
exceptionTranslationFilter = postProcess(exceptionTranslationFilter);
|
||||
http.addFilter(exceptionTranslationFilter);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -199,6 +199,7 @@ public final class HttpBasicConfigurer<B extends HttpSecurityBuilder<B>>
|
|||
if (rememberMeServices != null) {
|
||||
basicAuthenticationFilter.setRememberMeServices(rememberMeServices);
|
||||
}
|
||||
basicAuthenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
basicAuthenticationFilter = postProcess(basicAuthenticationFilter);
|
||||
http.addFilter(basicAuthenticationFilter);
|
||||
}
|
||||
|
|
|
@ -329,6 +329,7 @@ public final class LogoutConfigurer<H extends HttpSecurityBuilder<H>>
|
|||
this.logoutHandlers.add(postProcess(new LogoutSuccessEventPublishingLogoutHandler()));
|
||||
LogoutHandler[] handlers = this.logoutHandlers.toArray(new LogoutHandler[0]);
|
||||
LogoutFilter result = new LogoutFilter(getLogoutSuccessHandler(), handlers);
|
||||
result.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
result.setLogoutRequestMatcher(getLogoutRequestMatcher(http));
|
||||
result = postProcess(result);
|
||||
return result;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -108,11 +108,13 @@ public final class SecurityContextConfigurer<H extends HttpSecurityBuilder<H>>
|
|||
if (this.requireExplicitSave) {
|
||||
SecurityContextHolderFilter securityContextHolderFilter = postProcess(
|
||||
new SecurityContextHolderFilter(securityContextRepository));
|
||||
securityContextHolderFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
http.addFilter(securityContextHolderFilter);
|
||||
}
|
||||
else {
|
||||
SecurityContextPersistenceFilter securityContextFilter = new SecurityContextPersistenceFilter(
|
||||
securityContextRepository);
|
||||
securityContextFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
SessionManagementConfigurer<?> sessionManagement = http.getConfigurer(SessionManagementConfigurer.class);
|
||||
SessionCreationPolicy sessionCreationPolicy = (sessionManagement != null)
|
||||
? sessionManagement.getSessionCreationPolicy() : null;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -370,6 +370,7 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
|
|||
if (trustResolver != null) {
|
||||
sessionManagementFilter.setTrustResolver(trustResolver);
|
||||
}
|
||||
sessionManagementFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||
sessionManagementFilter = postProcess(sessionManagementFilter);
|
||||
http.addFilter(sessionManagementFilter);
|
||||
if (isConcurrentSessionControlEnabled()) {
|
||||
|
@ -500,7 +501,6 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
|
|||
concurrentSessionControlStrategy.setMaximumSessions(this.maximumSessions);
|
||||
concurrentSessionControlStrategy.setExceptionIfMaximumExceeded(this.maxSessionsPreventsLogin);
|
||||
concurrentSessionControlStrategy = postProcess(concurrentSessionControlStrategy);
|
||||
|
||||
RegisterSessionAuthenticationStrategy registerSessionStrategy = new RegisterSessionAuthenticationStrategy(
|
||||
sessionRegistry);
|
||||
registerSessionStrategy = postProcess(registerSessionStrategy);
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.config;
|
||||
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.core.context.SecurityContextImpl;
|
||||
|
||||
public class MockSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
|
||||
|
||||
private SecurityContext context;
|
||||
|
||||
@Override
|
||||
public void clearContext() {
|
||||
this.context = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityContext getContext() {
|
||||
if (this.context == null) {
|
||||
this.context = createEmptyContext();
|
||||
}
|
||||
return this.context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(SecurityContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityContext createEmptyContext() {
|
||||
return new SecurityContextImpl();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.config.annotation;
|
||||
|
||||
import org.mockito.ArgumentMatcher;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextChangedEvent;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
|
||||
public final class SecurityContextChangedListenerArgumentMatchers {
|
||||
|
||||
public static SecurityContextChangedEvent setAuthentication(Class<? extends Authentication> authenticationClass) {
|
||||
return argThat(new ArgumentMatcher<SecurityContextChangedEvent>() {
|
||||
public boolean matches(SecurityContextChangedEvent event) {
|
||||
Authentication previous = authentication(event.getOldContext());
|
||||
Authentication next = authentication(event.getNewContext());
|
||||
return previous == null && next != null && authenticationClass.isAssignableFrom(next.getClass());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "authentication set to " + authenticationClass;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Authentication authentication(SecurityContext context) {
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
return context.getAuthentication();
|
||||
}
|
||||
|
||||
private SecurityContextChangedListenerArgumentMatchers() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.config.annotation;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.MockSecurityContextHolderStrategy;
|
||||
import org.springframework.security.core.context.ListeningSecurityContextHolderStrategy;
|
||||
import org.springframework.security.core.context.SecurityContextChangedListener;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
@Configuration
|
||||
public class SecurityContextChangedListenerConfig {
|
||||
|
||||
private SecurityContextHolderStrategy strategy = new MockSecurityContextHolderStrategy();
|
||||
|
||||
private SecurityContextChangedListener listener = mock(SecurityContextChangedListener.class);
|
||||
|
||||
@Bean
|
||||
SecurityContextHolderStrategy securityContextHolderStrategy() {
|
||||
return spy(new ListeningSecurityContextHolderStrategy(this.strategy, this.listener));
|
||||
}
|
||||
|
||||
@Bean
|
||||
SecurityContextChangedListener securityContextChangedListener() {
|
||||
return this.listener;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,6 +20,8 @@ import org.junit.jupiter.api.Test;
|
|||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
|
@ -27,13 +29,16 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
|||
import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.core.context.SecurityContextChangedListener;
|
||||
import org.springframework.security.core.userdetails.PasswordEncodedUser;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.security.config.Customizer.withDefaults;
|
||||
import static org.springframework.security.config.annotation.SecurityContextChangedListenerArgumentMatchers.setAuthentication;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
@ -62,6 +67,16 @@ public class AnonymousConfigurerTests {
|
|||
this.mockMvc.perform(get("/")).andExpect(content().string("principal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenCustomSecurityContextHolderStrategyThenUses() throws Exception {
|
||||
this.spring.register(AnonymousPrincipalInLambdaConfig.class, SecurityContextChangedListenerConfig.class,
|
||||
PrincipalController.class).autowire();
|
||||
this.mockMvc.perform(get("/")).andExpect(content().string("principal"));
|
||||
SecurityContextChangedListener listener = this.spring.getContext()
|
||||
.getBean(SecurityContextChangedListener.class);
|
||||
verify(listener).securityContextChanged(setAuthentication(AnonymousAuthenticationToken.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWhenAnonymousDisabledInLambdaThenRespondsWithForbidden() throws Exception {
|
||||
this.spring.register(AnonymousDisabledInLambdaConfig.class, PrincipalController.class).autowire();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -26,7 +26,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
|
@ -34,6 +36,8 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
|||
import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.context.SecurityContextChangedListener;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
@ -47,6 +51,7 @@ import static org.mockito.Mockito.atLeastOnce;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.security.config.annotation.SecurityContextChangedListenerArgumentMatchers.setAuthentication;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
@ -192,6 +197,17 @@ public class ExceptionHandlingConfigurerTests {
|
|||
.resolveMediaTypes(any(NativeWebRequest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWhenCustomSecurityContextHolderStrategyThenUsed() throws Exception {
|
||||
this.spring.register(SecurityContextChangedListenerConfig.class, DefaultSecurityConfig.class).autowire();
|
||||
this.mvc.perform(get("/"));
|
||||
SecurityContextHolderStrategy strategy = this.spring.getContext().getBean(SecurityContextHolderStrategy.class);
|
||||
verify(strategy, atLeastOnce()).getContext();
|
||||
SecurityContextChangedListener listener = this.spring.getContext()
|
||||
.getBean(SecurityContextChangedListener.class);
|
||||
verify(listener).securityContextChanged(setAuthentication(AnonymousAuthenticationToken.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWhenUsingDefaultsAndUnauthenticatedThenRedirectsToLogin() throws Exception {
|
||||
this.spring.register(DefaultHttpConfig.class).autowire();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -21,7 +21,9 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
|
@ -30,6 +32,8 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
|||
import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.config.users.AuthenticationTestConfiguration;
|
||||
import org.springframework.security.core.context.SecurityContextChangedListener;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.core.userdetails.PasswordEncodedUser;
|
||||
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders;
|
||||
import org.springframework.security.web.PortMapper;
|
||||
|
@ -42,10 +46,12 @@ import org.springframework.test.web.servlet.MockMvc;
|
|||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.security.config.Customizer.withDefaults;
|
||||
import static org.springframework.security.config.annotation.SecurityContextChangedListenerArgumentMatchers.setAuthentication;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.logout;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
||||
|
@ -97,6 +103,24 @@ public class FormLoginConfigurerTests {
|
|||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formLoginWhenSecurityContextHolderStrategyThenUses() throws Exception {
|
||||
this.spring.register(FormLoginConfig.class, SecurityContextChangedListenerConfig.class).autowire();
|
||||
// @formatter:off
|
||||
SecurityMockMvcRequestBuilders.FormLoginRequestBuilder loginRequest = formLogin()
|
||||
.user("username", "user")
|
||||
.password("password", "password");
|
||||
this.mockMvc.perform(loginRequest)
|
||||
.andExpect(status().isFound())
|
||||
.andExpect(redirectedUrl("/"));
|
||||
// @formatter:on
|
||||
SecurityContextHolderStrategy strategy = this.spring.getContext().getBean(SecurityContextHolderStrategy.class);
|
||||
verify(strategy, atLeastOnce()).getContext();
|
||||
SecurityContextChangedListener listener = this.spring.getContext()
|
||||
.getBean(SecurityContextChangedListener.class);
|
||||
verify(listener).securityContextChanged(setAuthentication(UsernamePasswordAuthenticationToken.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginWhenFormLoginConfiguredThenHasDefaultFailureUrl() throws Exception {
|
||||
this.spring.register(FormLoginConfig.class).autowire();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -25,8 +25,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
|
@ -35,6 +37,7 @@ import org.springframework.security.config.test.SpringTestContext;
|
|||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.core.context.SecurityContextChangedListener;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
|
@ -53,6 +56,7 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.security.config.Customizer.withDefaults;
|
||||
import static org.springframework.security.config.annotation.SecurityContextChangedListenerArgumentMatchers.setAuthentication;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
|
@ -133,6 +137,17 @@ public class HttpBasicConfigurerTests {
|
|||
.andExpect(content().string("user"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void httpBasicWhenCustomSecurityContextHolderStrategyThenUses() throws Exception {
|
||||
this.spring.register(HttpBasic.class, Users.class, Home.class, SecurityContextChangedListenerConfig.class)
|
||||
.autowire();
|
||||
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isOk())
|
||||
.andExpect(content().string("user"));
|
||||
SecurityContextChangedListener listener = this.spring.getContext()
|
||||
.getBean(SecurityContextChangedListener.class);
|
||||
verify(listener).securityContextChanged(setAuthentication(UsernamePasswordAuthenticationToken.class));
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
|
|
Loading…
Reference in New Issue