mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
Adapt to Spring Security changes
Closes gh-32604
This commit is contained in:
parent
2e74878ba4
commit
ce3c933f77
@ -34,6 +34,10 @@ import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.context.DelegatingSecurityContextRepository;
|
||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@ -67,6 +71,8 @@ public class ManagementWebSecurityAutoConfiguration {
|
||||
}
|
||||
http.formLogin(Customizer.withDefaults());
|
||||
http.httpBasic(Customizer.withDefaults());
|
||||
http.setSharedObject(SecurityContextRepository.class, new DelegatingSecurityContextRepository(
|
||||
new RequestAttributeSecurityContextRepository(), new HttpSessionSecurityContextRepository()));
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
@ -32,8 +32,8 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.access.event.AbstractAuthorizationEvent;
|
||||
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationEvent;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -149,7 +149,7 @@ class AuditAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(AbstractAuthorizationEvent event) {
|
||||
public void onApplicationEvent(AuthorizationEvent event) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
@ -177,22 +178,15 @@ abstract class AbstractEndpointRequestIntegrationTests {
|
||||
static class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("deprecation")
|
||||
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() {
|
||||
return new org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter() {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.requestMatchers(EndpointRequest.toLinks()).permitAll();
|
||||
requests.requestMatchers(EndpointRequest.to(TestEndpoint1.class)).permitAll();
|
||||
requests.requestMatchers(EndpointRequest.toAnyEndpoint()).authenticated();
|
||||
requests.anyRequest().hasRole("ADMIN");
|
||||
});
|
||||
http.httpBasic();
|
||||
}
|
||||
|
||||
};
|
||||
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.requestMatchers(EndpointRequest.toLinks()).permitAll();
|
||||
requests.requestMatchers(EndpointRequest.to(TestEndpoint1.class)).permitAll();
|
||||
requests.requestMatchers(EndpointRequest.toAnyEndpoint()).authenticated();
|
||||
requests.anyRequest().hasRole("ADMIN");
|
||||
});
|
||||
http.httpBasic();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -172,18 +172,17 @@ class ManagementWebSecurityAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@SuppressWarnings("deprecation")
|
||||
static class CustomSecurityConfiguration
|
||||
extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter {
|
||||
static class CustomSecurityConfiguration {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
@Bean
|
||||
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.antMatchers("/foo").permitAll();
|
||||
requests.requestMatchers(new AntPathRequestMatcher("/foo")).permitAll();
|
||||
requests.anyRequest().authenticated();
|
||||
});
|
||||
http.formLogin(Customizer.withDefaults());
|
||||
http.httpBasic();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -193,8 +192,8 @@ class ManagementWebSecurityAutoConfigurationTests {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
|
||||
.build();
|
||||
return http.securityMatcher("/**")
|
||||
.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -205,8 +204,10 @@ class ManagementWebSecurityAutoConfigurationTests {
|
||||
@Bean
|
||||
@Order(SecurityProperties.BASIC_AUTH_ORDER - 1)
|
||||
SecurityFilterChain testRemoteDevToolsSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
return http.requestMatcher(new AntPathRequestMatcher("/**")).authorizeHttpRequests().anyRequest()
|
||||
.anonymous().and().csrf().disable().build();
|
||||
http.securityMatcher(new AntPathRequestMatcher("/**"));
|
||||
http.authorizeHttpRequests().anyRequest().anonymous();
|
||||
http.csrf().disable();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
@ -55,9 +54,7 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.AccessDecisionVoter;
|
||||
import org.springframework.security.access.SecurityConfig;
|
||||
import org.springframework.security.access.vote.RoleVoter;
|
||||
import org.springframework.security.authorization.AuthorityAuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
@ -469,7 +466,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
|
||||
private static final class ReactiveSecurityContext implements SecurityContext {
|
||||
|
||||
private final RoleVoter roleVoter = new RoleVoter();
|
||||
private static final String ROLE_PREFIX = "ROLE_";
|
||||
|
||||
private final Authentication authentication;
|
||||
|
||||
@ -477,6 +474,10 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
||||
private Authentication getAuthentication() {
|
||||
return this.authentication;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getPrincipal() {
|
||||
return this.authentication;
|
||||
@ -484,11 +485,9 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
if (!role.startsWith(this.roleVoter.getRolePrefix())) {
|
||||
role = this.roleVoter.getRolePrefix() + role;
|
||||
}
|
||||
return this.roleVoter.vote(this.authentication, null,
|
||||
Collections.singletonList(new SecurityConfig(role))) == AccessDecisionVoter.ACCESS_GRANTED;
|
||||
String authority = (!role.startsWith(ROLE_PREFIX)) ? ROLE_PREFIX + role : role;
|
||||
return AuthorityAuthorizationManager.hasAuthority(authority).check(this::getAuthentication, null)
|
||||
.isGranted();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,18 +21,21 @@ import org.springframework.boot.actuate.audit.listener.AuditApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.security.access.event.AbstractAuthorizationEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationGrantedEvent;
|
||||
|
||||
/**
|
||||
* Abstract {@link ApplicationListener} to expose Spring Security
|
||||
* {@link AbstractAuthorizationEvent authorization events} as {@link AuditEvent}s.
|
||||
* {@link AuthorizationDeniedEvent authorization denied} and
|
||||
* {@link AuthorizationGrantedEvent authorization granted} events as {@link AuditEvent}s.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Vedran Pavic
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public abstract class AbstractAuthorizationAuditListener
|
||||
implements ApplicationListener<AbstractAuthorizationEvent>, ApplicationEventPublisherAware {
|
||||
implements ApplicationListener<AuthorizationEvent>, ApplicationEventPublisherAware {
|
||||
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.springframework.boot.actuate.security;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.audit.AuditEvent;
|
||||
@ -75,7 +76,7 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList
|
||||
}
|
||||
|
||||
private void onAuthenticationFailureEvent(AbstractAuthenticationFailureEvent event) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("type", event.getException().getClass().getName());
|
||||
data.put("message", event.getException().getMessage());
|
||||
if (event.getAuthentication().getDetails() != null) {
|
||||
@ -85,7 +86,7 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList
|
||||
}
|
||||
|
||||
private void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
if (event.getAuthentication().getDetails() != null) {
|
||||
data.put("details", event.getAuthentication().getDetails());
|
||||
}
|
||||
|
@ -16,13 +16,14 @@
|
||||
|
||||
package org.springframework.boot.actuate.security;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.boot.actuate.audit.AuditEvent;
|
||||
import org.springframework.security.access.event.AbstractAuthorizationEvent;
|
||||
import org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent;
|
||||
import org.springframework.security.access.event.AuthorizationFailureEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationEvent;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link AbstractAuthorizationAuditListener}.
|
||||
@ -39,30 +40,38 @@ public class AuthorizationAuditListener extends AbstractAuthorizationAuditListen
|
||||
public static final String AUTHORIZATION_FAILURE = "AUTHORIZATION_FAILURE";
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(AbstractAuthorizationEvent event) {
|
||||
if (event instanceof AuthenticationCredentialsNotFoundEvent credentialsNotFoundEvent) {
|
||||
onAuthenticationCredentialsNotFoundEvent(credentialsNotFoundEvent);
|
||||
}
|
||||
else if (event instanceof AuthorizationFailureEvent authorizationFailureEvent) {
|
||||
onAuthorizationFailureEvent(authorizationFailureEvent);
|
||||
public void onApplicationEvent(AuthorizationEvent event) {
|
||||
if (event instanceof AuthorizationDeniedEvent<?> authorizationDeniedEvent) {
|
||||
onAuthorizationDeniedEvent(authorizationDeniedEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private void onAuthenticationCredentialsNotFoundEvent(AuthenticationCredentialsNotFoundEvent event) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("type", event.getCredentialsNotFoundException().getClass().getName());
|
||||
data.put("message", event.getCredentialsNotFoundException().getMessage());
|
||||
publish(new AuditEvent("<unknown>", AuthenticationAuditListener.AUTHENTICATION_FAILURE, data));
|
||||
private void onAuthorizationDeniedEvent(AuthorizationDeniedEvent<?> event) {
|
||||
String name = getName(event.getAuthentication());
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
Object details = getDetails(event.getAuthentication());
|
||||
if (details != null) {
|
||||
data.put("details", details);
|
||||
}
|
||||
publish(new AuditEvent(name, AUTHORIZATION_FAILURE, data));
|
||||
}
|
||||
|
||||
private void onAuthorizationFailureEvent(AuthorizationFailureEvent event) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("type", event.getAccessDeniedException().getClass().getName());
|
||||
data.put("message", event.getAccessDeniedException().getMessage());
|
||||
if (event.getAuthentication().getDetails() != null) {
|
||||
data.put("details", event.getAuthentication().getDetails());
|
||||
private String getName(Supplier<Authentication> authentication) {
|
||||
try {
|
||||
return authentication.get().getName();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
private Object getDetails(Supplier<Authentication> authentication) {
|
||||
try {
|
||||
return authentication.get().getDetails();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
publish(new AuditEvent(event.getAuthentication().getName(), AUTHORIZATION_FAILURE, data));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,21 +16,17 @@
|
||||
|
||||
package org.springframework.boot.actuate.security;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.springframework.boot.actuate.audit.AuditEvent;
|
||||
import org.springframework.boot.actuate.audit.listener.AuditApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.SecurityConfig;
|
||||
import org.springframework.security.access.event.AbstractAuthorizationEvent;
|
||||
import org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent;
|
||||
import org.springframework.security.access.event.AuthorizationFailureEvent;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationEvent;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
@ -51,35 +47,48 @@ class AuthorizationAuditListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthenticationCredentialsNotFound() {
|
||||
AuditApplicationEvent event = handleAuthorizationEvent(
|
||||
new AuthenticationCredentialsNotFoundEvent(this, Collections.singletonList(new SecurityConfig("USER")),
|
||||
new AuthenticationCredentialsNotFoundException("Bad user")));
|
||||
assertThat(event.getAuditEvent().getType()).isEqualTo(AuthenticationAuditListener.AUTHENTICATION_FAILURE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthorizationFailure() {
|
||||
AuditApplicationEvent event = handleAuthorizationEvent(new AuthorizationFailureEvent(this,
|
||||
Collections.singletonList(new SecurityConfig("USER")),
|
||||
new UsernamePasswordAuthenticationToken("user", "password"), new AccessDeniedException("Bad user")));
|
||||
assertThat(event.getAuditEvent().getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDetailsAreIncludedInAuditEvent() {
|
||||
Object details = new Object();
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("user",
|
||||
void authorizationDeniedEvent() {
|
||||
AuthorizationDecision decision = new AuthorizationDecision(false);
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("spring",
|
||||
"password");
|
||||
authentication.setDetails(details);
|
||||
AuditApplicationEvent event = handleAuthorizationEvent(
|
||||
new AuthorizationFailureEvent(this, Collections.singletonList(new SecurityConfig("USER")),
|
||||
authentication, new AccessDeniedException("Bad user")));
|
||||
assertThat(event.getAuditEvent().getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE);
|
||||
assertThat(event.getAuditEvent().getData()).containsEntry("details", details);
|
||||
authentication.setDetails("details");
|
||||
AuthorizationDeniedEvent<?> authorizationEvent = new AuthorizationDeniedEvent<>(() -> authentication, "",
|
||||
decision);
|
||||
AuditEvent auditEvent = handleAuthorizationEvent(authorizationEvent).getAuditEvent();
|
||||
assertThat(auditEvent.getPrincipal()).isEqualTo("spring");
|
||||
assertThat(auditEvent.getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE);
|
||||
assertThat(auditEvent.getData()).containsEntry("details", "details");
|
||||
}
|
||||
|
||||
private AuditApplicationEvent handleAuthorizationEvent(AbstractAuthorizationEvent event) {
|
||||
@Test
|
||||
void authorizationDeniedEventWhenAuthenticationIsNotAvailable() {
|
||||
AuthorizationDecision decision = new AuthorizationDecision(false);
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("spring",
|
||||
"password");
|
||||
authentication.setDetails("details");
|
||||
AuthorizationDeniedEvent<?> authorizationEvent = new AuthorizationDeniedEvent<>(() -> {
|
||||
throw new RuntimeException("No authentication");
|
||||
}, "", decision);
|
||||
AuditEvent auditEvent = handleAuthorizationEvent(authorizationEvent).getAuditEvent();
|
||||
assertThat(auditEvent.getPrincipal()).isEqualTo("<unknown>");
|
||||
assertThat(auditEvent.getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE);
|
||||
assertThat(auditEvent.getData()).doesNotContainKey("details");
|
||||
}
|
||||
|
||||
@Test
|
||||
void authorizationDeniedEventWhenAuthenticationDoesNotHaveDetails() {
|
||||
AuthorizationDecision decision = new AuthorizationDecision(false);
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("spring",
|
||||
"password");
|
||||
AuthorizationDeniedEvent<?> authorizationEvent = new AuthorizationDeniedEvent<>(() -> authentication, "",
|
||||
decision);
|
||||
AuditEvent auditEvent = handleAuthorizationEvent(authorizationEvent).getAuditEvent();
|
||||
assertThat(auditEvent.getPrincipal()).isEqualTo("spring");
|
||||
assertThat(auditEvent.getType()).isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE);
|
||||
assertThat(auditEvent.getData()).doesNotContainKey("details");
|
||||
}
|
||||
|
||||
private AuditApplicationEvent handleAuthorizationEvent(AuthorizationEvent event) {
|
||||
ArgumentCaptor<AuditApplicationEvent> eventCaptor = ArgumentCaptor.forClass(AuditApplicationEvent.class);
|
||||
this.listener.onApplicationEvent(event);
|
||||
then(this.publisher).should().publishEvent(eventCaptor.capture());
|
||||
|
@ -40,10 +40,7 @@ class DefaultWebSecurityCondition extends AllNestedConditions {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean({
|
||||
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.class,
|
||||
SecurityFilterChain.class })
|
||||
@SuppressWarnings("deprecation")
|
||||
@ConditionalOnMissingBean({ SecurityFilterChain.class })
|
||||
static class Beans {
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfi
|
||||
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for OAuth2 resource server support.
|
||||
|
@ -29,6 +29,10 @@ import org.springframework.security.config.BeanIds;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.context.DelegatingSecurityContextRepository;
|
||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
|
||||
/**
|
||||
* {@link Configuration @Configuration} class securing servlet applications.
|
||||
@ -57,6 +61,8 @@ class SpringBootWebSecurityConfiguration {
|
||||
http.authorizeHttpRequests().anyRequest().authenticated();
|
||||
http.formLogin();
|
||||
http.httpBasic();
|
||||
http.setSharedObject(SecurityContextRepository.class, new DelegatingSecurityContextRepository(
|
||||
new RequestAttributeSecurityContextRepository(), new HttpSessionSecurityContextRepository()));
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationManagerResolver;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
@ -72,7 +71,6 @@ public class UserDetailsServiceAutoConfiguration {
|
||||
private static final Log logger = LogFactory.getLog(UserDetailsServiceAutoConfiguration.class);
|
||||
|
||||
@Bean
|
||||
@Lazy
|
||||
public InMemoryUserDetailsManager inMemoryUserDetailsManager(SecurityProperties properties,
|
||||
ObjectProvider<PasswordEncoder> passwordEncoder) {
|
||||
SecurityProperties.User user = properties.getUser();
|
||||
|
@ -32,7 +32,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -166,7 +166,7 @@ class AopAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@EnableMethodSecurity(prePostEnabled = true)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class EnableGlobalMethodSecurityConfiguration {
|
||||
|
||||
|
@ -38,7 +38,7 @@ import org.springframework.graphql.execution.SecurityDataFetcherExceptionResolve
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
@ -151,7 +151,7 @@ class GraphQlWebMvcSecurityAutoConfigurationTests {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@EnableMethodSecurity(prePostEnabled = true)
|
||||
@SuppressWarnings("deprecation")
|
||||
static class SecurityConfig {
|
||||
|
||||
|
@ -22,9 +22,11 @@ import java.util.List;
|
||||
import jakarta.servlet.Filter;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -56,7 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class OAuth2WebSecurityConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
void securityConfigurerConfiguresOAuth2Login() {
|
||||
@ -113,21 +115,10 @@ class OAuth2WebSecurityConfigurationTests {
|
||||
.run((context) -> assertThat(context).hasSingleBean(OAuth2AuthorizedClientRepository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void securityFilterChainConfigBacksOffWhenOtherWebSecurityAdapterPresent() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TestWebSecurityConfigurerConfig.class, OAuth2WebSecurityConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(getFilters(context, OAuth2LoginAuthenticationFilter.class)).isEmpty();
|
||||
assertThat(getFilters(context, OAuth2AuthorizationCodeGrantFilter.class)).isEmpty();
|
||||
assertThat(context).getBean(OAuth2AuthorizedClientService.class).isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void securityFilterChainConfigBacksOffWhenOtherSecurityFilterChainBeanPresent() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TestSecurityFilterChainConfig.class, OAuth2WebSecurityConfiguration.class)
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class))
|
||||
.withUserConfiguration(TestSecurityFilterChainConfiguration.class, OAuth2WebSecurityConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(getFilters(context, OAuth2LoginAuthenticationFilter.class)).isEmpty();
|
||||
assertThat(getFilters(context, OAuth2AuthorizationCodeGrantFilter.class)).isEmpty();
|
||||
@ -164,7 +155,7 @@ class OAuth2WebSecurityConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
private List<Filter> getFilters(AssertableApplicationContext context, Class<? extends Filter> filter) {
|
||||
private List<Filter> getFilters(AssertableWebApplicationContext context, Class<? extends Filter> filter) {
|
||||
FilterChainProxy filterChain = (FilterChainProxy) context.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN);
|
||||
List<SecurityFilterChain> filterChains = filterChain.getFilterChains();
|
||||
List<Filter> filters = filterChains.get(0).getFilters();
|
||||
@ -228,20 +219,12 @@ class OAuth2WebSecurityConfigurationTests {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(ClientRegistrationRepositoryConfiguration.class)
|
||||
@SuppressWarnings("deprecation")
|
||||
static class TestWebSecurityConfigurerConfig
|
||||
extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(ClientRegistrationRepositoryConfiguration.class)
|
||||
static class TestSecurityFilterChainConfig {
|
||||
static class TestSecurityFilterChainConfiguration {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
|
||||
.build();
|
||||
return http.securityMatcher("/**")
|
||||
.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build();
|
||||
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
|
||||
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.SupplierReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.OpaqueTokenReactiveAuthenticationManager;
|
||||
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
|
||||
|
@ -37,6 +37,7 @@ import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
@ -57,10 +58,10 @@ import org.springframework.security.oauth2.jwt.JwtIssuerValidator;
|
||||
import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.SupplierJwtDecoder;
|
||||
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
|
||||
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
|
||||
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter;
|
||||
import org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter;
|
||||
import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
@ -579,7 +580,7 @@ class OAuth2ResourceServerAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
void jwtSecurityConfigurerBacksOffWhenSecurityFilterChainBeanIsPresent() {
|
||||
this.contextRunner
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class))
|
||||
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com")
|
||||
.withUserConfiguration(JwtDecoderConfig.class, TestSecurityFilterChainConfig.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(SecurityFilterChain.class));
|
||||
@ -587,7 +588,8 @@ class OAuth2ResourceServerAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
void opaqueTokenSecurityConfigurerBacksOffWhenSecurityFilterChainBeanIsPresent() {
|
||||
this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfig.class)
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class))
|
||||
.withUserConfiguration(TestSecurityFilterChainConfig.class)
|
||||
.withPropertyValues(
|
||||
"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://check-token.com",
|
||||
"spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id",
|
||||
@ -692,8 +694,9 @@ class OAuth2ResourceServerAutoConfigurationTests {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
|
||||
.build();
|
||||
http.securityMatcher("/**");
|
||||
http.authorizeHttpRequests().anyRequest().authenticated();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
@ -41,7 +42,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
|
||||
import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding;
|
||||
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
|
||||
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
|
||||
import org.springframework.security.saml2.provider.service.web.authentication.logout.Saml2LogoutRequestFilter;
|
||||
import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
@ -205,17 +206,10 @@ class Saml2RelyingPartyAutoConfigurationTests {
|
||||
.run((context) -> assertThat(hasFilter(context, Saml2WebSsoAuthenticationFilter.class)).isTrue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void samlLoginShouldBackOffWhenAWebSecurityConfigurerAdapterIsDefined() {
|
||||
this.contextRunner.withUserConfiguration(WebSecurityConfigurerAdapterConfiguration.class)
|
||||
.withPropertyValues(getPropertyValues())
|
||||
.run((context) -> assertThat(hasFilter(context, Saml2WebSsoAuthenticationFilter.class)).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void samlLoginShouldBackOffWhenASecurityFilterChainBeanIsPresent() {
|
||||
this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfig.class)
|
||||
.withPropertyValues(getPropertyValues())
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class))
|
||||
.withUserConfiguration(TestSecurityFilterChainConfig.class).withPropertyValues(getPropertyValues())
|
||||
.run((context) -> assertThat(hasFilter(context, Saml2WebSsoAuthenticationFilter.class)).isFalse());
|
||||
}
|
||||
|
||||
@ -303,26 +297,13 @@ class Saml2RelyingPartyAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class WebSecurityConfigurerAdapterConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("deprecation")
|
||||
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() {
|
||||
return new org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter() {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestSecurityFilterChainConfig {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
|
||||
.build();
|
||||
return http.securityMatcher("/**")
|
||||
.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@ -45,7 +46,6 @@ import org.springframework.security.authentication.AuthenticationEventPublisher;
|
||||
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
|
||||
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;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
|
||||
@ -89,30 +89,11 @@ class SecurityAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
void securityConfigurerBacksOffWhenOtherSecurityFilterChainBeanPresent() {
|
||||
this.contextRunner.withUserConfiguration(TestSecurityFilterChainConfig.class).run((context) -> {
|
||||
assertThat(context.getBeansOfType(SecurityFilterChain.class).size()).isEqualTo(1);
|
||||
assertThat(context.containsBean("testSecurityFilterChain")).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void securityConfigurerBacksOffWhenOtherWebSecurityAdapterBeanPresent() {
|
||||
this.contextRunner.withUserConfiguration(WebSecurity.class).run((context) -> {
|
||||
assertThat(context.getBeansOfType(
|
||||
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.class)
|
||||
.size()).isEqualTo(1);
|
||||
assertThat(context.containsBean("securityAutoConfigurationTests.WebSecurity")).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultFilterOrderWithSecurityAdapter() {
|
||||
this.contextRunner
|
||||
.withConfiguration(AutoConfigurations.of(WebSecurity.class, SecurityFilterAutoConfiguration.class))
|
||||
.run((context) -> assertThat(
|
||||
context.getBean("securityFilterChainRegistration", DelegatingFilterProxyRegistrationBean.class)
|
||||
.getOrder()).isEqualTo(OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER - 100));
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class))
|
||||
.withUserConfiguration(TestSecurityFilterChainConfig.class).run((context) -> {
|
||||
assertThat(context.getBeansOfType(SecurityFilterChain.class).size()).isEqualTo(1);
|
||||
assertThat(context.containsBean("testSecurityFilterChain")).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -255,21 +236,13 @@ class SecurityAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableWebSecurity
|
||||
@SuppressWarnings("deprecation")
|
||||
static class WebSecurity
|
||||
extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestSecurityFilterChainConfig {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain testSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
return http.antMatcher("/**").authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
|
||||
.build();
|
||||
return http.securityMatcher("/**")
|
||||
.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).build();
|
||||
|
||||
}
|
||||
|
||||
@ -281,7 +254,7 @@ class SecurityAutoConfigurationTests {
|
||||
@Bean
|
||||
@ConfigurationPropertiesBinding
|
||||
Converter<String, TargetType> targetTypeConverter() {
|
||||
return new Converter<String, TargetType>() {
|
||||
return new Converter<>() {
|
||||
|
||||
@Override
|
||||
public TargetType convert(String input) {
|
||||
|
@ -22,7 +22,6 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfigurationTests.WebSecurity;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.ConverterBean;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.DeserializerBean;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.ExampleController;
|
||||
@ -53,7 +52,7 @@ class SecurityFilterAutoConfigurationTests {
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import({ DeserializerBean.class, JacksonModuleBean.class, ExampleController.class, ConverterBean.class })
|
||||
@ImportAutoConfiguration({ WebMvcAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebSecurity.class,
|
||||
HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
|
||||
SecurityFilterAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
static class Config {
|
||||
|
||||
|
@ -36,7 +36,6 @@ import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.ProviderManager;
|
||||
import org.springframework.security.authentication.TestingAuthenticationProvider;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
@ -164,12 +163,6 @@ class UserDetailsServiceAutoConfigurationTests {
|
||||
.run(((context) -> assertThat(context).doesNotHaveBean(InMemoryUserDetailsManager.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void generatedPasswordShouldNotBePrintedIfAuthenticationManagerBuilderIsUsed(CapturedOutput output) {
|
||||
this.contextRunner.withUserConfiguration(TestConfigWithAuthenticationManagerBuilder.class)
|
||||
.run(((context) -> assertThat(output).doesNotContain("Using generated security password: ")));
|
||||
}
|
||||
|
||||
private void testPasswordEncoding(Class<?> configClass, String providedPassword, String expectedPassword) {
|
||||
this.contextRunner.withUserConfiguration(configClass)
|
||||
.withPropertyValues("spring.security.user.password=" + providedPassword).run(((context) -> {
|
||||
@ -264,24 +257,6 @@ class UserDetailsServiceAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(TestSecurityConfiguration.class)
|
||||
static class TestConfigWithAuthenticationManagerBuilder {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("deprecation")
|
||||
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() {
|
||||
return new org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter() {
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication().withUser("hero").password("{noop}hero").roles("HERO", "USER").and()
|
||||
.withUser("user").password("{noop}user").roles("USER");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestAuthenticationManagerResolverConfiguration {
|
||||
|
||||
|
@ -1497,7 +1497,7 @@ bom {
|
||||
]
|
||||
}
|
||||
}
|
||||
library("Spring Security", "6.0.0-M7") {
|
||||
library("Spring Security", "6.0.0-SNAPSHOT") {
|
||||
group("org.springframework.security") {
|
||||
imports = [
|
||||
"spring-security-bom"
|
||||
|
@ -17,7 +17,6 @@
|
||||
package org.springframework.boot.devtools.autoconfigure;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -47,11 +46,10 @@ class RemoteDevtoolsSecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
@Order(SecurityProperties.BASIC_AUTH_ORDER - 1)
|
||||
@ConditionalOnMissingBean(org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.class)
|
||||
@SuppressWarnings("deprecation")
|
||||
SecurityFilterChain devtoolsSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.requestMatcher(new AntPathRequestMatcher(this.url)).authorizeHttpRequests().anyRequest().anonymous().and()
|
||||
.csrf().disable();
|
||||
http.securityMatcher(new AntPathRequestMatcher(this.url));
|
||||
http.authorizeHttpRequests().anyRequest().anonymous();
|
||||
http.csrf().disable();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,6 @@ import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.security.config.BeanIds;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
@ -183,25 +182,6 @@ class RemoteDevToolsAutoConfigurationTests {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/my-path")).andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
void securityConfigurationWhenWebSecurityConfigurerAdapterIsFound2() throws Exception {
|
||||
this.context = getContext(() -> {
|
||||
AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();
|
||||
context.setServletContext(new MockServletContext());
|
||||
context.register(Config.class, PropertyPlaceholderAutoConfiguration.class,
|
||||
TestWebSecurityConfigurerAdapter.class);
|
||||
TestPropertyValues.of("spring.devtools.remote.secret:supersecret").applyTo(context);
|
||||
context.refresh();
|
||||
return context;
|
||||
});
|
||||
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(springSecurity()).addFilter(filter)
|
||||
.build();
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(DEFAULT_CONTEXT_PATH + "/restart").header(DEFAULT_SECRET_HEADER_NAME,
|
||||
"supersecret")).andExpect(status().isOk());
|
||||
assertRestartInvoked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void disableRestart() throws Exception {
|
||||
this.context = getContext(() -> loadContext("spring.devtools.remote.secret:supersecret",
|
||||
@ -270,18 +250,6 @@ class RemoteDevToolsAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@SuppressWarnings("deprecation")
|
||||
static class TestWebSecurityConfigurerAdapter
|
||||
extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.antMatcher("/foo/**").authorizeHttpRequests().anyRequest().authenticated().and().httpBasic();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock {@link HttpRestartServer} implementation.
|
||||
*/
|
||||
|
@ -212,8 +212,8 @@ You can use the configprop:management.endpoints.web.exposure.include[] property
|
||||
|
||||
NOTE: Before setting the `management.endpoints.web.exposure.include`, ensure that the exposed actuators do not contain sensitive information, are secured by placing them behind a firewall, or are secured by something like Spring Security.
|
||||
|
||||
If Spring Security is on the classpath and no other `WebSecurityConfigurerAdapter` or `SecurityFilterChain` bean is present, all actuators other than `/health` are secured by Spring Boot auto-configuration.
|
||||
If you define a custom `WebSecurityConfigurerAdapter` or `SecurityFilterChain` bean, Spring Boot auto-configuration backs off and lets you fully control the actuator access rules.
|
||||
If Spring Security is on the classpath and no other `SecurityFilterChain` bean is present, all actuators other than `/health` are secured by Spring Boot auto-configuration.
|
||||
If you define a custom `SecurityFilterChain` bean, Spring Boot auto-configuration backs off and lets you fully control the actuator access rules.
|
||||
|
||||
If you wish to configure custom security for HTTP endpoints (for example, to allow only users with a certain role to access them), Spring Boot provides some convenient `RequestMatcher` objects that you can use in combination with Spring Security.
|
||||
|
||||
|
@ -8,7 +8,7 @@ For more about Spring Security, see the {spring-security}[Spring Security projec
|
||||
|
||||
[[howto.security.switch-off-spring-boot-configuration]]
|
||||
=== Switch off the Spring Boot Security Configuration
|
||||
If you define a `@Configuration` with a `WebSecurityConfigurerAdapter` or a `SecurityFilterChain` bean in your application, it switches off the default webapp security settings in Spring Boot.
|
||||
If you define a `@Configuration` with a `SecurityFilterChain` bean in your application, it switches off the default webapp security settings in Spring Boot.
|
||||
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ To switch off the default web application security configuration completely or t
|
||||
|
||||
To also switch off the `UserDetailsService` configuration, you can add a bean of type `UserDetailsService`, `AuthenticationProvider`, or `AuthenticationManager`.
|
||||
|
||||
Access rules can be overridden by adding a custom `SecurityFilterChain` or `WebSecurityConfigurerAdapter` bean.
|
||||
Access rules can be overridden by adding a custom `SecurityFilterChain` bean.
|
||||
Spring Boot provides convenience methods that can be used to override access rules for actuator endpoints and static resources.
|
||||
`EndpointRequest` can be used to create a `RequestMatcher` that is based on the configprop:management.endpoints.web.base-path[] property.
|
||||
`PathRequest` can be used to create a `RequestMatcher` for resources in commonly used locations.
|
||||
|
@ -27,7 +27,7 @@ public class MySecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.requestMatcher(EndpointRequest.toAnyEndpoint());
|
||||
http.securityMatcher(EndpointRequest.toAnyEndpoint());
|
||||
http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll());
|
||||
return http.build();
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class MySecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.requestMatcher(EndpointRequest.toAnyEndpoint());
|
||||
http.securityMatcher(EndpointRequest.toAnyEndpoint());
|
||||
http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
|
||||
http.httpBasic(withDefaults());
|
||||
return http.build();
|
||||
|
@ -33,7 +33,7 @@ public class DevProfileSecurityConfiguration {
|
||||
@Bean
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
SecurityFilterChain h2ConsoleSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.requestMatcher(PathRequest.toH2Console());
|
||||
http.securityMatcher(PathRequest.toH2Console());
|
||||
http.authorizeHttpRequests(yourCustomAuthorization());
|
||||
http.csrf((csrf) -> csrf.disable());
|
||||
http.headers((headers) -> headers.frameOptions().sameOrigin());
|
||||
|
@ -27,7 +27,7 @@ class MySecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests {
|
||||
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests {
|
||||
requests -> requests.anyRequest().permitAll() }
|
||||
return http.build()
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class MySecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests ->
|
||||
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests ->
|
||||
requests.anyRequest().hasRole("ENDPOINT_ADMIN")
|
||||
}
|
||||
http.httpBasic()
|
||||
|
@ -60,7 +60,6 @@ class WebMvcTypeExcludeFilterTests {
|
||||
assertThat(excludes(filter, ExampleMessageConverter.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleWebSecurityConfigurer.class)).isFalse();
|
||||
assertThat(excludes(filter, SecurityFilterChain.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleHandlerInterceptor.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleModule.class)).isFalse();
|
||||
@ -78,7 +77,6 @@ class WebMvcTypeExcludeFilterTests {
|
||||
assertThat(excludes(filter, ExampleMessageConverter.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleWebSecurityConfigurer.class)).isFalse();
|
||||
assertThat(excludes(filter, SecurityFilterChain.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleHandlerInterceptor.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleModule.class)).isFalse();
|
||||
@ -96,7 +94,6 @@ class WebMvcTypeExcludeFilterTests {
|
||||
assertThat(excludes(filter, ExampleMessageConverter.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleWebSecurityConfigurer.class)).isTrue();
|
||||
assertThat(excludes(filter, SecurityFilterChain.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleHandlerInterceptor.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleModule.class)).isTrue();
|
||||
@ -130,7 +127,6 @@ class WebMvcTypeExcludeFilterTests {
|
||||
assertThat(excludes(filter, ExampleMessageConverter.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleWebSecurityConfigurer.class)).isFalse();
|
||||
assertThat(excludes(filter, SecurityFilterChain.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleHandlerInterceptor.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleModule.class)).isFalse();
|
||||
@ -204,12 +200,6 @@ class WebMvcTypeExcludeFilterTests {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
static class ExampleWebSecurityConfigurer
|
||||
extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter {
|
||||
|
||||
}
|
||||
|
||||
static class ExampleHandlerInterceptor implements HandlerInterceptor {
|
||||
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class EncodePasswordCommand extends OptionParsingCommand {
|
||||
Map<String, Supplier<PasswordEncoder>> encoders = new LinkedHashMap<>();
|
||||
encoders.put("default", PasswordEncoderFactories::createDelegatingPasswordEncoder);
|
||||
encoders.put("bcrypt", BCryptPasswordEncoder::new);
|
||||
encoders.put("pbkdf2", Pbkdf2PasswordEncoder::new);
|
||||
encoders.put("pbkdf2", Pbkdf2PasswordEncoder::defaultsForSpringSecurity_v5_8);
|
||||
ENCODERS = Collections.unmodifiableMap(encoders);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,8 @@ class EncodePasswordCommandTests {
|
||||
ExitStatus status = command.run("-a", "pbkdf2", "boot");
|
||||
then(this.log).should().info(this.message.capture());
|
||||
assertThat(this.message.getValue()).doesNotStartWith("{");
|
||||
assertThat(new Pbkdf2PasswordEncoder().matches("boot", this.message.getValue())).isTrue();
|
||||
assertThat(Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8().matches("boot", this.message.getValue()))
|
||||
.isTrue();
|
||||
assertThat(status).isEqualTo(ExitStatus.OK);
|
||||
}
|
||||
|
||||
|
@ -56,14 +56,14 @@ public class SecurityConfiguration {
|
||||
@Bean
|
||||
SecurityFilterChain configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.mvcMatchers("/actuator/beans").hasRole("BEANS");
|
||||
requests.requestMatchers("/actuator/beans").hasRole("BEANS");
|
||||
requests.requestMatchers(EndpointRequest.to("health")).permitAll();
|
||||
requests.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class))
|
||||
.hasRole("ACTUATOR");
|
||||
requests.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll();
|
||||
requests.antMatchers("/foo").permitAll();
|
||||
requests.antMatchers("/error").permitAll();
|
||||
requests.antMatchers("/**").hasRole("USER");
|
||||
requests.requestMatchers("/foo").permitAll();
|
||||
requests.requestMatchers("/error").permitAll();
|
||||
requests.requestMatchers("/**").hasRole("USER");
|
||||
});
|
||||
http.cors(Customizer.withDefaults());
|
||||
http.httpBasic();
|
||||
|
@ -128,7 +128,8 @@ abstract class AbstractSampleActuatorCustomSecurityTests {
|
||||
|
||||
@Test
|
||||
void secureServletEndpointWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity("/actuator/se1", String.class);
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/se1",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/se1/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
|
@ -18,7 +18,7 @@ package smoketest.graphql;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
@ -30,7 +30,7 @@ import static org.springframework.security.config.Customizer.withDefaults;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@EnableMethodSecurity(prePostEnabled = true)
|
||||
public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
|
@ -40,15 +40,14 @@ public class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http.authorizeHttpRequests()
|
||||
.requestMatchers(EndpointRequest.to("health")).permitAll()
|
||||
.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class)).hasRole("ACTUATOR")
|
||||
.antMatchers("/**").hasRole("USER")
|
||||
.and()
|
||||
.httpBasic();
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.requestMatchers(EndpointRequest.to("health")).permitAll();
|
||||
requests.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class))
|
||||
.hasRole("ACTUATOR");
|
||||
requests.requestMatchers("/**").hasRole("USER");
|
||||
});
|
||||
http.httpBasic();
|
||||
return http.build();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan
|
||||
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
|
||||
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true)
|
||||
public class SampleSecureApplication implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
|
@ -26,6 +26,7 @@ import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -62,7 +63,8 @@ class SampleSecureApplicationTests {
|
||||
|
||||
@Test
|
||||
void authenticated() {
|
||||
SecurityContextHolder.getContext().setAuthentication(this.authentication);
|
||||
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("user", "N/A",
|
||||
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")));
|
||||
assertThat("Hello Security").isEqualTo(this.service.secure());
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-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 smoketest.session.hazelcast;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
/**
|
||||
* Security configuration.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll();
|
||||
requests.anyRequest().authenticated();
|
||||
});
|
||||
http.formLogin(Customizer.withDefaults());
|
||||
http.httpBasic(Customizer.withDefaults());
|
||||
http.csrf().disable();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ package smoketest.session.hazelcast;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -27,11 +28,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -50,10 +55,7 @@ class SampleSessionHazelcastApplicationTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void sessionsEndpointShouldReturnUserSession() {
|
||||
URI uri = URI.create("/");
|
||||
ResponseEntity<String> firstResponse = performRequest(uri, null);
|
||||
String cookie = firstResponse.getHeaders().getFirst("Set-Cookie");
|
||||
performRequest(uri, cookie).getBody();
|
||||
performLogin();
|
||||
ResponseEntity<Map<String, Object>> entity = getSessions();
|
||||
assertThat(entity).isNotNull();
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@ -61,29 +63,21 @@ class SampleSessionHazelcastApplicationTests {
|
||||
assertThat(sessions.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
private ResponseEntity<String> performRequest(URI uri, String cookie) {
|
||||
HttpHeaders headers = getHeaders(cookie);
|
||||
RequestEntity<Object> request = new RequestEntity<>(headers, HttpMethod.GET, uri);
|
||||
return this.restTemplate.exchange(request, String.class);
|
||||
}
|
||||
|
||||
private HttpHeaders getHeaders(String cookie) {
|
||||
private String performLogin() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (cookie != null) {
|
||||
headers.set("Cookie", cookie);
|
||||
}
|
||||
else {
|
||||
headers.set("Authorization", getBasicAuth());
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private String getBasicAuth() {
|
||||
return "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes());
|
||||
headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
|
||||
form.set("username", "user");
|
||||
form.set("password", "password");
|
||||
ResponseEntity<String> entity = this.restTemplate.exchange("/login", HttpMethod.POST,
|
||||
new HttpEntity<>(form, headers), String.class);
|
||||
return entity.getHeaders().getFirst("Set-Cookie");
|
||||
}
|
||||
|
||||
private ResponseEntity<Map<String, Object>> getSessions() {
|
||||
HttpHeaders headers = getHeaders(null);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("Authorization", getBasicAuth());
|
||||
RequestEntity<Object> request = new RequestEntity<>(headers, HttpMethod.GET,
|
||||
URI.create("/actuator/sessions?username=user"));
|
||||
ParameterizedTypeReference<Map<String, Object>> stringObjectMap = new ParameterizedTypeReference<Map<String, Object>>() {
|
||||
@ -91,4 +85,8 @@ class SampleSessionHazelcastApplicationTests {
|
||||
return this.restTemplate.exchange(request, stringObjectMap);
|
||||
}
|
||||
|
||||
private String getBasicAuth() {
|
||||
return "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-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 smoketest.session;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
/**
|
||||
* Security configuration.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll();
|
||||
requests.anyRequest().authenticated();
|
||||
});
|
||||
http.formLogin(Customizer.withDefaults());
|
||||
http.httpBasic(Customizer.withDefaults());
|
||||
http.csrf().disable();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ package smoketest.session;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -27,11 +28,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -53,9 +58,8 @@ class SampleSessionJdbcApplicationTests {
|
||||
|
||||
@Test
|
||||
void sessionExpiry() throws Exception {
|
||||
ResponseEntity<String> firstResponse = performRequest(ROOT_URI, null);
|
||||
String sessionId1 = firstResponse.getBody();
|
||||
String cookie = firstResponse.getHeaders().getFirst("Set-Cookie");
|
||||
String cookie = performLogin();
|
||||
String sessionId1 = performRequest(ROOT_URI, cookie).getBody();
|
||||
String sessionId2 = performRequest(ROOT_URI, cookie).getBody();
|
||||
assertThat(sessionId1).isEqualTo(sessionId2);
|
||||
Thread.sleep(2100);
|
||||
@ -63,10 +67,22 @@ class SampleSessionJdbcApplicationTests {
|
||||
assertThat(loginPage).containsIgnoringCase("login");
|
||||
}
|
||||
|
||||
private String performLogin() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
|
||||
form.set("username", "user");
|
||||
form.set("password", "password");
|
||||
ResponseEntity<String> entity = this.restTemplate.exchange("/login", HttpMethod.POST,
|
||||
new HttpEntity<>(form, headers), String.class);
|
||||
return entity.getHeaders().getFirst("Set-Cookie");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void sessionsEndpointShouldReturnUserSession() {
|
||||
performRequest(ROOT_URI, null);
|
||||
performLogin();
|
||||
ResponseEntity<Map<String, Object>> response = getSessions();
|
||||
assertThat(response).isNotNull();
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-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 smoketest.session.mongodb;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
/**
|
||||
* Security configuration.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll();
|
||||
requests.anyRequest().authenticated();
|
||||
});
|
||||
http.formLogin(Customizer.withDefaults());
|
||||
http.httpBasic(Customizer.withDefaults());
|
||||
http.csrf().disable();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ package smoketest.session.mongodb;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -32,13 +33,17 @@ import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -69,7 +74,7 @@ public class SampleSessionMongoApplicationTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void sessionsEndpointShouldReturnUserSessions() {
|
||||
createSession(URI.create("/"));
|
||||
performLogin();
|
||||
ResponseEntity<Map<String, Object>> response = getSessions();
|
||||
assertThat(response).isNotNull();
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@ -86,9 +91,16 @@ public class SampleSessionMongoApplicationTests {
|
||||
assertThat(entity.getBody()).contains("maxWireVersion");
|
||||
}
|
||||
|
||||
private void createSession(URI uri) {
|
||||
RequestEntity<Object> request = getRequestEntity(uri);
|
||||
this.restTemplate.exchange(request, String.class);
|
||||
private String performLogin() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
|
||||
form.set("username", "user");
|
||||
form.set("password", "password");
|
||||
ResponseEntity<String> entity = this.restTemplate.exchange("/login", HttpMethod.POST,
|
||||
new HttpEntity<>(form, headers), String.class);
|
||||
return entity.getHeaders().getFirst("Set-Cookie");
|
||||
}
|
||||
|
||||
private RequestEntity<Object> getRequestEntity(URI uri) {
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-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 smoketest.session.redis;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
/**
|
||||
* Security configuration.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll();
|
||||
requests.anyRequest().authenticated();
|
||||
});
|
||||
http.formLogin(Customizer.withDefaults());
|
||||
http.httpBasic(Customizer.withDefaults());
|
||||
http.csrf().disable();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
package smoketest.session.redis;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -29,13 +30,17 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -63,7 +68,7 @@ public class SampleSessionRedisApplicationTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void sessionsEndpointShouldReturnUserSessions() {
|
||||
createSession(URI.create("/"));
|
||||
performLogin();
|
||||
ResponseEntity<Map<String, Object>> response = this.getSessions();
|
||||
assertThat(response).isNotNull();
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@ -71,9 +76,16 @@ public class SampleSessionRedisApplicationTests {
|
||||
assertThat(sessions.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
private void createSession(URI uri) {
|
||||
RequestEntity<Object> request = getRequestEntity(uri);
|
||||
this.restTemplate.exchange(request, String.class);
|
||||
private String performLogin() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML));
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
|
||||
form.set("username", "user");
|
||||
form.set("password", "password");
|
||||
ResponseEntity<String> entity = this.restTemplate.exchange("/login", HttpMethod.POST,
|
||||
new HttpEntity<>(form, headers), String.class);
|
||||
return entity.getHeaders().getFirst("Set-Cookie");
|
||||
}
|
||||
|
||||
private RequestEntity<Object> getRequestEntity(URI uri) {
|
||||
|
@ -24,18 +24,20 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableGlobalMethodSecurity(securedEnabled = true)
|
||||
@EnableMethodSecurity(securedEnabled = true)
|
||||
public class SampleMethodSecurityApplication implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
@ -69,8 +71,8 @@ public class SampleMethodSecurityApplication implements WebMvcConfigurer {
|
||||
@Bean
|
||||
SecurityFilterChain configure(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable();
|
||||
http.authorizeHttpRequests(
|
||||
(requests) -> requests.anyRequest().fullyAuthenticated().shouldFilterAllDispatcherTypes(false));
|
||||
http.authorizeHttpRequests((requests) -> requests.anyRequest().fullyAuthenticated());
|
||||
http.httpBasic();
|
||||
http.formLogin((form) -> form.loginPage("/login").permitAll());
|
||||
http.exceptionHandling((exceptions) -> exceptions.accessDeniedPage("/access"));
|
||||
return http.build();
|
||||
@ -85,10 +87,10 @@ public class SampleMethodSecurityApplication implements WebMvcConfigurer {
|
||||
@Bean
|
||||
SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable();
|
||||
http.requestMatcher(EndpointRequest.toAnyEndpoint());
|
||||
http.authorizeHttpRequests(
|
||||
(requests) -> requests.anyRequest().authenticated().shouldFilterAllDispatcherTypes(false));
|
||||
http.securityMatcher(EndpointRequest.toAnyEndpoint());
|
||||
http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
|
||||
http.httpBasic();
|
||||
http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository());
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
|
||||
/**
|
||||
* Tests to ensure that the error page with a custom servlet path is accessible only to
|
||||
@ -45,10 +47,11 @@ class CustomServletPathErrorPageTests extends AbstractErrorPageTests {
|
||||
@Bean
|
||||
SecurityFilterChain configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.antMatchers("/custom/servlet/path/public/**").permitAll();
|
||||
requests.requestMatchers("/public/**").permitAll();
|
||||
requests.anyRequest().fullyAuthenticated();
|
||||
});
|
||||
http.httpBasic();
|
||||
http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository());
|
||||
http.formLogin((form) -> form.loginPage("/custom/servlet/path/login").permitAll());
|
||||
return http.build();
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
|
||||
/**
|
||||
* Tests for error page that permits access to all with a custom servlet path.
|
||||
@ -44,10 +46,11 @@ class CustomServletPathUnauthenticatedErrorPageTests extends AbstractUnauthentic
|
||||
@Bean
|
||||
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.antMatchers("/custom/servlet/path/error").permitAll();
|
||||
requests.antMatchers("/custom/servlet/path/public/**").permitAll();
|
||||
requests.requestMatchers("/error").permitAll();
|
||||
requests.requestMatchers("/public/**").permitAll();
|
||||
requests.anyRequest().authenticated();
|
||||
});
|
||||
http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository());
|
||||
http.httpBasic();
|
||||
return http.build();
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
|
||||
/**
|
||||
* Tests to ensure that the error page is accessible only to authorized users.
|
||||
@ -44,9 +46,10 @@ class ErrorPageTests extends AbstractErrorPageTests {
|
||||
@Bean
|
||||
SecurityFilterChain configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.antMatchers("/public/**").permitAll();
|
||||
requests.requestMatchers("/public/**").permitAll();
|
||||
requests.anyRequest().fullyAuthenticated();
|
||||
});
|
||||
http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository());
|
||||
http.httpBasic();
|
||||
http.formLogin((form) -> form.loginPage("/login").permitAll());
|
||||
return http.build();
|
||||
|
@ -46,7 +46,7 @@ class NoSessionErrorPageTests extends AbstractErrorPageTests {
|
||||
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests((requests) -> {
|
||||
requests.antMatchers("/public/**").permitAll();
|
||||
requests.requestMatchers("/public/**").permitAll();
|
||||
requests.anyRequest().authenticated();
|
||||
});
|
||||
http.httpBasic();
|
||||
|
@ -96,7 +96,7 @@ class SampleWebSecureApplicationTests {
|
||||
SecurityFilterChain configure(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable();
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.antMatchers("/public/**").permitAll();
|
||||
requests.requestMatchers("/public/**").permitAll();
|
||||
requests.anyRequest().fullyAuthenticated();
|
||||
});
|
||||
http.httpBasic();
|
||||
|
@ -21,6 +21,8 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
|
||||
/**
|
||||
* Tests for error page that permits access to all.
|
||||
@ -44,10 +46,11 @@ class UnauthenticatedErrorPageTests extends AbstractUnauthenticatedErrorPageTest
|
||||
@Bean
|
||||
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests((requests) -> {
|
||||
requests.antMatchers("/error").permitAll();
|
||||
requests.antMatchers("/public/**").permitAll();
|
||||
requests.requestMatchers("/error").permitAll();
|
||||
requests.requestMatchers("/public/**").permitAll();
|
||||
requests.anyRequest().authenticated();
|
||||
});
|
||||
http.setSharedObject(SecurityContextRepository.class, new RequestAttributeSecurityContextRepository());
|
||||
http.httpBasic();
|
||||
return http.build();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user