1
0
mirror of synced 2026-07-10 13:20:02 +00:00

Compare commits

...

44 Commits

Author SHA1 Message Date
github-actions[bot] 54f7eacae6 Release 6.0.6 2023-08-21 15:20:33 +00:00
Josh Cummings 5fb6f5768c Merge branch '5.8.x' into 6.0.x
Closes gh-13666 in 6.0.x
Closes gh-13721
2023-08-20 23:07:36 -06:00
Josh Cummings 28f98b3351 Improve Error Message
Closes gh-13667
2023-08-20 22:53:57 -06:00
Josh Cummings ed96e2cddf Ignore Unmappable Servlets
Closes gh-13666
2023-08-20 22:53:55 -06:00
Steve Riesenberg 97f6ca6f82 Merge branch '5.8.x' into 6.0.x 2023-08-18 16:08:57 -05:00
Steve Riesenberg ecc20ceffd Update spring-ldap-core to 3.0.5
Closes gh-13714
2023-08-18 16:01:18 -05:00
Steve Riesenberg e147b22130 Update org.springframework.data to 2022.0.9
Closes gh-13713
2023-08-18 16:01:15 -05:00
Steve Riesenberg d2cddb7e2d Update org.aspectj to 1.9.20
Closes gh-13712
2023-08-18 16:01:12 -05:00
Steve Riesenberg 67e1832922 Update io.projectreactor to 2022.0.10
Closes gh-13710
2023-08-18 16:01:07 -05:00
Steve Riesenberg 0426d27698 Update mockk to 1.13.7
Closes gh-13709
2023-08-18 16:01:03 -05:00
Steve Riesenberg 7afadfc0ef Update micrometer-observation to 1.10.10
Closes gh-13708
2023-08-18 16:01:00 -05:00
Steve Riesenberg 5f2a8c46d7 Update logback-classic to 1.4.11
Closes gh-13707
2023-08-18 16:00:57 -05:00
Steve Riesenberg 7200f76ac1 Update org.springframework.data to 2021.2.15
Closes gh-13705
2023-08-18 15:58:36 -05:00
Steve Riesenberg 094b71b329 Update org.aspectj to 1.9.20
Closes gh-13704
2023-08-18 15:58:33 -05:00
Steve Riesenberg 491f0f647c Update io.projectreactor to 2020.0.35
Closes gh-13702
2023-08-18 15:58:27 -05:00
Josh Cummings ca0140c586 saml2Login Honors AuthenticationProvider bean
Closes gh-13654
2023-08-16 17:54:14 -06:00
Marcus Da Coregio 17e9fec6eb Merge branch '5.8.x' into 6.0.x 2023-08-09 09:55:39 -03:00
Mario Petrovski 1db8734101 Closes #11450 Add Java beans configuration for Remmember Me Docs 2023-08-09 09:54:53 -03:00
bigfang b5f42b509b Fix Typo in Getting Started Docs
Closes gh-13605
2023-08-08 18:17:51 -06:00
Seongguk Jeong 90936537dc Update links in adocs
Spring Security 6.0 requires Spring 6.0 as a minimum and Spring 6.0 requires a minimum of Tomcat 10/Jetty 11

Closes gh-13565
2023-08-08 17:45:07 -06:00
Guillaume Husta a8fcfaa428 Doc : typo in Custom DSLs section
Method 'configure' was renamed 'filterChain'
2023-08-08 17:26:25 -06:00
Josh Cummings c20100dab7 Merge branch '5.8.x' into 6.0.x 2023-08-07 15:31:20 -06:00
Kawin Naipongprasit 4b44a2d924 Adapeter to Adapter 2023-08-07 15:25:47 -06:00
Josh Cummings 1f27b18398 Merge branch '5.8.x' into 6.0.x 2023-08-07 14:48:12 -06:00
Daniel Shuy e8b9a35494 Fix Bearer Token RestTemplate Support example 2023-08-07 14:47:37 -06:00
Rob Winch c4b773b150 Merge branch '5.8.x' into 6.0.x
Use includeGroupByRegex

This makes the include more robust

Issue gh-13582
2023-08-07 10:27:32 -05:00
Rob Winch 82e5f62079 Use includeGroupByRegex
This makes the include more robust

Issue gh-13582
2023-08-07 10:26:57 -05:00
Rob Winch 4257a97504 Merge branch '5.8.x' into 6.0.x
Dependencies are resolved from appropriate repositories

Closes gh-13622
2023-08-07 09:51:55 -05:00
Eric Haag 30bc2634d7 Optimize configuration of project repositories
This change applies repository content filtering to configured
repositories, reducing the time spent during dependency resolution.

This fixes an issue where requests for 'org.opensaml',
'net.shibboleth.utilities' and 'net.minidev' dependencies were being
made in the Spring releases repositories, resulting in many failed
requests during dependency resolution and increased resolution times.

Closes gh-13582
2023-08-07 09:51:42 -05:00
Marcus Da Coregio 461d6edd85 Merge branch '5.8.x' into 6.0.x
Closes gh-13589
2023-07-27 11:23:58 -03:00
Marcus Da Coregio 13ca7ac4d4 Referrer-Policy is added by default in Reactive applications
Closes gh-13561
2023-07-27 11:22:21 -03:00
Josh Cummings ee13216882 Merge branch '5.8.x' into 6.0.x
Closes gh-13579
2023-07-24 11:31:29 -06:00
Josh Cummings c4f061c63d Do Not Re-register Method Security Advisors
Closes gh-13572
2023-07-24 11:24:03 -06:00
Marcus Da Coregio 0d2315cf3a Merge branch '5.8.x' into 6.0.x 2023-07-18 09:52:08 -03:00
Marcus Da Coregio 2c6d053ceb Merge branch '5.7.x' into 5.8.x 2023-07-18 09:51:45 -03:00
Marcus Da Coregio ff4745a461 Merge branch '5.6.x' into 5.7.x 2023-07-18 09:51:19 -03:00
github-actions[bot] 76b5d17c83 Next development version 2023-07-17 21:56:07 +00:00
github-actions[bot] 38a7ffcc9b Next development version 2023-07-17 21:52:14 +00:00
github-actions[bot] 6f55fc60bb Next development version 2023-07-17 21:46:35 +00:00
github-actions[bot] d0491c07e9 Next development version 2023-07-17 21:42:28 +00:00
github-actions[bot] 486c5118d2 Release 5.7.10 2023-07-17 21:05:15 +00:00
github-actions[bot] d02ab50577 Release 5.8.5 2023-07-17 21:04:33 +00:00
github-actions[bot] 17d8293be1 Release 5.6.12 2023-07-17 21:00:49 +00:00
github-actions[bot] 0686b461af Release 6.0.5 2023-07-17 20:43:30 +00:00
22 changed files with 191 additions and 62 deletions
+1 -1
View File
@@ -86,7 +86,7 @@ dependencies {
implementation localGroovy()
implementation 'io.github.gradle-nexus:publish-plugin:1.1.0'
implementation 'io.projectreactor:reactor-core:3.5.8'
implementation 'io.projectreactor:reactor-core:3.5.9'
implementation 'org.gretty:gretty:3.0.9'
implementation 'com.apollographql.apollo:apollo-runtime:2.4.5'
implementation 'com.github.ben-manes:gradle-versions-plugin:0.38.0'
@@ -34,6 +34,14 @@ class RepositoryConventionPlugin implements Plugin<Project> {
if (forceMavenRepositories?.contains('local')) {
mavenLocal()
}
maven {
name = 'shibboleth'
url = 'https://build.shibboleth.net/nexus/content/repositories/releases/'
content {
includeGroupByRegex('org\\.opensaml.*')
includeGroupByRegex('net\\.shibboleth.*')
}
}
mavenCentral()
if (isSnapshot) {
maven {
@@ -67,12 +75,11 @@ class RepositoryConventionPlugin implements Plugin<Project> {
password project.artifactoryPassword
}
}
content {
excludeGroup('net.minidev')
}
url = 'https://repo.spring.io/release/'
}
maven {
name = 'shibboleth'
url = 'https://build.shibboleth.net/nexus/content/repositories/releases/'
}
}
}
@@ -125,27 +125,27 @@ public class RepositoryConventionPluginTests {
private void assertSnapshotRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(5);
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://repo.spring.io/snapshot/");
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
.isEqualTo("https://repo.spring.io/snapshot/");
assertThat(((MavenArtifactRepository) repositories.get(3)).getUrl().toString())
.isEqualTo("https://repo.spring.io/milestone/");
}
private void assertMilestoneRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(4);
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
.isEqualTo("https://repo.spring.io/milestone/");
}
private void assertReleaseRepository(RepositoryHandler repositories) {
assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(3);
assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString())
.isEqualTo("https://repo.maven.apache.org/maven2/");
assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString())
.isEqualTo("https://repo.spring.io/release/");
}
-4
View File
@@ -4,10 +4,6 @@ apply plugin: 'io.spring.convention.spring-module'
apply plugin: 'trang'
apply plugin: 'kotlin'
repositories {
maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
}
dependencies {
management platform(project(":spring-security-dependencies"))
// NB: Don't add other compile time dependencies to the config module as this breaks tooling
@@ -36,6 +36,10 @@ class MethodSecurityAdvisorRegistrar implements ImportBeanDefinitionRegistrar {
}
private void registerAsAdvisor(String prefix, BeanDefinitionRegistry registry) {
String advisorName = prefix + "Advisor";
if (registry.containsBeanDefinition(advisorName)) {
return;
}
String interceptorName = prefix + "MethodInterceptor";
if (!registry.containsBeanDefinition(interceptorName)) {
return;
@@ -18,6 +18,8 @@ package org.springframework.security.config.annotation.web;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -194,18 +196,31 @@ public abstract class AbstractRequestMatcherRegistry<C> {
if (servletContext == null) {
return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
}
Map<String, ? extends ServletRegistration> registrations = servletContext.getServletRegistrations();
if (registrations == null) {
Map<String, ? extends ServletRegistration> registrations = mappableServletRegistrations(servletContext);
if (registrations.isEmpty()) {
return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
}
if (!hasDispatcherServlet(registrations)) {
return requestMatchers(RequestMatchers.antMatchersAsArray(method, patterns));
}
Assert.isTrue(registrations.size() == 1,
"This method cannot decide whether these patterns are Spring MVC patterns or not. If this endpoint is a Spring MVC endpoint, please use requestMatchers(MvcRequestMatcher); otherwise, please use requestMatchers(AntPathRequestMatcher).");
if (registrations.size() > 1) {
String errorMessage = computeErrorMessage(registrations.values());
throw new IllegalArgumentException(errorMessage);
}
return requestMatchers(createMvcMatchers(method, patterns).toArray(new RequestMatcher[0]));
}
private Map<String, ? extends ServletRegistration> mappableServletRegistrations(ServletContext servletContext) {
Map<String, ServletRegistration> mappable = new LinkedHashMap<>();
for (Map.Entry<String, ? extends ServletRegistration> entry : servletContext.getServletRegistrations()
.entrySet()) {
if (!entry.getValue().getMappings().isEmpty()) {
mappable.put(entry.getKey(), entry.getValue());
}
}
return mappable;
}
private boolean hasDispatcherServlet(Map<String, ? extends ServletRegistration> registrations) {
if (registrations == null) {
return false;
@@ -226,6 +241,19 @@ public abstract class AbstractRequestMatcherRegistry<C> {
return false;
}
private String computeErrorMessage(Collection<? extends ServletRegistration> registrations) {
String template = "This method cannot decide whether these patterns are Spring MVC patterns or not. "
+ "If this endpoint is a Spring MVC endpoint, please use requestMatchers(MvcRequestMatcher); "
+ "otherwise, please use requestMatchers(AntPathRequestMatcher).\n\n"
+ "This is because there is more than one mappable servlet in your servlet context: %s.\n\n"
+ "For each MvcRequestMatcher, call MvcRequestMatcher#setServletPath to indicate the servlet path.";
Map<String, Collection<String>> mappings = new LinkedHashMap<>();
for (ServletRegistration registration : registrations) {
mappings.put(registration.getClassName(), registration.getMappings());
}
return String.format(template, mappings);
}
/**
* <p>
* If the {@link HandlerMappingIntrospector} is available in the classpath, maps to an
@@ -269,6 +269,9 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
}
}
this.initDefaultLoginFilter(http);
if (this.authenticationManager == null) {
registerDefaultAuthenticationProvider(http);
}
}
/**
@@ -284,10 +287,7 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
filter.setAuthenticationRequestRepository(getAuthenticationRequestRepository(http));
http.addFilter(postProcess(filter));
super.configure(http);
if (this.authenticationManager == null) {
registerDefaultAuthenticationProvider(http);
}
else {
if (this.authenticationManager != null) {
this.saml2WebSsoAuthenticationFilter.setAuthenticationManager(this.authenticationManager);
}
}
@@ -361,7 +361,10 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
}
private void registerDefaultAuthenticationProvider(B http) {
http.authenticationProvider(postProcess(new OpenSaml4AuthenticationProvider()));
OpenSaml4AuthenticationProvider provider = getBeanOrNull(http, OpenSaml4AuthenticationProvider.class);
if (provider == null) {
http.authenticationProvider(postProcess(new OpenSaml4AuthenticationProvider()));
}
}
private void registerDefaultCsrfOverride(B http) {
@@ -16,8 +16,10 @@
package org.springframework.security.config;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -35,7 +37,7 @@ public class MockServletContext extends org.springframework.mock.web.MockServlet
public static MockServletContext mvc() {
MockServletContext servletContext = new MockServletContext();
servletContext.addServlet("dispatcherServlet", DispatcherServlet.class);
servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/");
return servletContext;
}
@@ -59,6 +61,8 @@ public class MockServletContext extends org.springframework.mock.web.MockServlet
private final Class<?> clazz;
private final Set<String> mappings = new LinkedHashSet<>();
MockServletRegistration(String name, Class<?> clazz) {
this.name = name;
this.clazz = clazz;
@@ -91,12 +95,13 @@ public class MockServletContext extends org.springframework.mock.web.MockServlet
@Override
public Set<String> addMapping(String... urlPatterns) {
return null;
this.mappings.addAll(Arrays.asList(urlPatterns));
return this.mappings;
}
@Override
public Collection<String> getMappings() {
return null;
return this.mappings;
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.aopalliance.intercept.MethodInterceptor;
@@ -64,6 +65,8 @@ import org.springframework.security.test.context.support.WithSecurityContextTest
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -418,6 +421,17 @@ public class PrePostMethodSecurityConfigurationTests {
assertThat(this.spring.getContext().containsBean("annotationSecurityAspect$0")).isFalse();
}
// gh-13572
@Test
public void configureWhenBeanOverridingDisallowedThenWorks() {
this.spring.register(MethodSecurityServiceConfig.class, BusinessServiceConfig.class)
.postProcessor(disallowBeanOverriding()).autowire();
}
private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
}
@Configuration
@EnableMethodSecurity
static class MethodSecurityServiceConfig {
@@ -174,12 +174,24 @@ public class AbstractRequestMatcherRegistryTests {
public void requestMatchersWhenAmbiguousServletsThenException() {
MockServletContext servletContext = new MockServletContext();
given(this.context.getServletContext()).willReturn(servletContext);
servletContext.addServlet("dispatcherServlet", DispatcherServlet.class);
servletContext.addServlet("servletTwo", Servlet.class);
servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/");
servletContext.addServlet("servletTwo", Servlet.class).addMapping("/servlet/**");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.matcherRegistry.requestMatchers("/**"));
}
@Test
public void requestMatchersWhenUnmappableServletsThenSkips() {
mockMvcIntrospector(true);
MockServletContext servletContext = new MockServletContext();
given(this.context.getServletContext()).willReturn(servletContext);
servletContext.addServlet("dispatcherServlet", DispatcherServlet.class).addMapping("/");
servletContext.addServlet("servletTwo", Servlet.class);
List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**");
assertThat(requestMatchers).hasSize(1);
assertThat(requestMatchers.get(0)).isInstanceOf(MvcRequestMatcher.class);
}
private void mockMvcIntrospector(boolean isPresent) {
ApplicationContext context = this.matcherRegistry.getApplicationContext();
given(context.containsBean("mvcHandlerMappingIntrospector")).willReturn(isPresent);
@@ -43,6 +43,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
@@ -60,6 +61,7 @@ import org.springframework.security.saml2.core.Saml2ErrorCodes;
import org.springframework.security.saml2.core.Saml2Utils;
import org.springframework.security.saml2.core.TestSaml2X509Credentials;
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
@@ -358,6 +360,15 @@ public class Saml2LoginConfigurerTests {
.andExpect(redirectedUrl("http://localhost/saml2/authenticate/registration-id"));
}
@Test
public void saml2LoginWhenCustomAuthenticationProviderThenUses() throws Exception {
this.spring.register(CustomAuthenticationProviderConfig.class).autowire();
AuthenticationProvider provider = this.spring.getContext().getBean(AuthenticationProvider.class);
this.mvc.perform(post("/login/saml2/sso/registration-id").param("SAMLResponse", SIGNED_RESPONSE))
.andExpect(status().isFound());
verify(provider).authenticate(any());
}
private void performSaml2Login(String expected) throws IOException, ServletException {
// setup authentication parameters
this.request.setRequestURI("/login/saml2/sso/registration-id");
@@ -668,6 +679,29 @@ public class Saml2LoginConfigurerTests {
}
@Configuration
@EnableWebSecurity
@EnableWebMvc
@Import(Saml2LoginConfigBeans.class)
static class CustomAuthenticationProviderConfig {
private final OpenSaml4AuthenticationProvider provider = spy(new OpenSaml4AuthenticationProvider());
@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())
.saml2Login(Customizer.withDefaults());
return http.build();
}
@Bean
AuthenticationProvider provider() {
return this.provider;
}
}
static class Saml2LoginConfigBeans {
@Bean
+4 -4
View File
@@ -12,12 +12,12 @@ dependencies {
api platform("io.rsocket:rsocket-bom:1.1.4")
api platform("org.junit:junit-bom:5.9.3")
api platform("org.mockito:mockito-bom:4.8.1")
api platform("org.springframework.data:spring-data-bom:2022.0.8")
api platform("org.springframework.data:spring-data-bom:2022.0.9")
api platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")
api platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4")
api platform("com.fasterxml.jackson:jackson-bom:2.14.3")
constraints {
api "ch.qos.logback:logback-classic:1.4.8"
api "ch.qos.logback:logback-classic:1.4.11"
api "com.google.inject:guice:3.0"
api "com.nimbusds:nimbus-jose-jwt:9.24.4"
api "com.nimbusds:oauth2-oidc-sdk:9.43.3"
@@ -25,7 +25,7 @@ dependencies {
api "com.squareup.okhttp3:okhttp:3.14.9"
api "com.unboundid:unboundid-ldapsdk:6.0.9"
api "commons-collections:commons-collections:3.2.2"
api "io.mockk:mockk:1.13.5"
api "io.mockk:mockk:1.13.7"
api "io.micrometer:micrometer-observation:$micrometerVersion"
api "jakarta.annotation:jakarta.annotation-api:2.1.1"
api "jakarta.inject:jakarta.inject-api:2.0.1"
@@ -67,7 +67,7 @@ dependencies {
api "org.skyscreamer:jsonassert:1.5.1"
api "org.slf4j:log4j-over-slf4j:1.7.36"
api "org.slf4j:slf4j-api:2.0.7"
api "org.springframework.ldap:spring-ldap-core:3.0.4"
api "org.springframework.ldap:spring-ldap-core:3.0.5"
api "org.synchronoss.cloud:nio-multipart-parser:1.1.0"
api 'org.apache.maven.resolver:maven-resolver-connector-basic:1.8.2'
api 'org.apache.maven.resolver:maven-resolver-impl:1.8.2'
@@ -25,7 +25,7 @@ Without proper configuration, the application server can not know that the load
To fix this, you can use https://tools.ietf.org/html/rfc7239[RFC 7239] to specify that a load balancer is being used.
To make the application aware of this, you need to configure your application server to be aware of the X-Forwarded headers.
For example, Tomcat uses https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html[`RemoteIpValve`] and Jetty uses https://download.eclipse.org/jetty/stable-9/apidocs/org/eclipse/jetty/server/ForwardedRequestCustomizer.html[`ForwardedRequestCustomizer`].
For example, Tomcat uses https://tomcat.apache.org/tomcat-10.1-doc/api/org/apache/catalina/valves/RemoteIpValve.html[`RemoteIpValve`] and Jetty uses https://eclipse.dev/jetty/javadoc/jetty-11/org/eclipse/jetty/server/ForwardedRequestCustomizer.html[`ForwardedRequestCustomizer`].
Alternatively, Spring users can use https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java[`ForwardedHeaderFilter`].
Spring Boot users can use the `server.use-forward-headers` property to configure the application.
@@ -191,7 +191,7 @@ Alternatively, you can manually add the starter:
[subs="verbatim,attributes"]
----
dependencies {
compile "org.springframework.boot:spring-boot-starter-security"
implementation "org.springframework.boot:spring-boot-starter-security"
}
----
@@ -245,8 +245,8 @@ A minimal Spring Security Maven set of dependencies typically looks like the fol
[subs="verbatim,attributes"]
----
dependencies {
compile "org.springframework.security:spring-security-web"
compile "org.springframework.security:spring-security-config"
implementation "org.springframework.security:spring-security-web"
implementation "org.springframework.security:spring-security-config"
}
----
@@ -448,8 +448,8 @@ fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
[[webflux-headers-referrer]]
== Referrer Policy
By default, Spring Security does not add xref:features/exploits/headers.adoc#headers-referrer[Referrer Policy] headers.
You can enable the Referrer Policy header using configuration as shown below:
Spring Security adds the xref:features/exploits/headers.adoc#headers-referrer[Referrer Policy] header by default with the directive `no-referrer`.
You can change the Referrer Policy header using configuration as shown below:
.Referrer Policy Configuration
[tabs]
@@ -7,7 +7,7 @@ Without proper configuration, the application server will not know that the load
To fix this you can use https://tools.ietf.org/html/rfc7239[RFC 7239] to specify that a load balancer is being used.
To make the application aware of this, you need to either configure your application server aware of the X-Forwarded headers.
For example Tomcat uses the https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html[RemoteIpValve] and Jetty uses https://www.eclipse.org/jetty/javadoc/jetty-9/org/eclipse/jetty/server/ForwardedRequestCustomizer.html[ForwardedRequestCustomizer].
For example Tomcat uses the https://tomcat.apache.org/tomcat-10.1-doc/api/org/apache/catalina/valves/RemoteIpValve.html[RemoteIpValve] and Jetty uses https://eclipse.dev/jetty/javadoc/jetty-11/org/eclipse/jetty/server/ForwardedRequestCustomizer.html[ForwardedRequestCustomizer].
Alternatively, Spring 4.3+ users can leverage https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java[ForwardedHeaderFilter].
Spring Boot users may use the `server.use-forward-headers` property to configure the application.
@@ -157,7 +157,39 @@ XML::
The following beans are required in an application context to enable remember-me services:
[source,xml]
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Bean
RememberMeAuthenticationFilter rememberMeFilter() {
RememberMeAuthenticationFilter rememberMeFilter = new RememberMeAuthenticationFilter();
rememberMeFilter.setRememberMeServices(rememberMeServices());
rememberMeFilter.setAuthenticationManager(theAuthenticationManager);
return rememberMeFilter;
}
@Bean
TokenBasedRememberMeServices rememberMeServices() {
TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices();
rememberMeServices.setUserDetailsService(myUserDetailsService);
rememberMeServices.setKey("springRocks");
return rememberMeServices;
}
@Bean
RememberMeAuthenticationProvider rememberMeAuthenticationProvider() {
RememberMeAuthenticationProvider rememberMeAuthenticationProvider = new RememberMeAuthenticationProvider();
rememberMeAuthenticationProvider.setKey("springRocks");
return rememberMeAuthenticationProvider;
}
----
XML::
+
[source,xml,role="secondary"]
----
<bean id="rememberMeFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
@@ -176,6 +208,7 @@ The following beans are required in an application context to enable remember-me
<property name="key" value="springRocks"/>
</bean>
----
======
Remember to add your `RememberMeServices` implementation to your `UsernamePasswordAuthenticationFilter.setRememberMeServices()` property, include the `RememberMeAuthenticationProvider` in your `AuthenticationManager.setProviders()` list, and add `RememberMeAuthenticationFilter` into your `FilterChainProxy` (typically immediately after your `UsernamePasswordAuthenticationFilter`).
@@ -13,7 +13,7 @@ It maps the certificate to an application user and loads that user's set of gran
You can also use SSL with "`mutual authentication`". The server then requests a valid certificate from the client as part of the SSL handshake.
The server authenticates the client by checking that its certificate is signed by an acceptable authority.
For example, if you use Tomcat, you should read the https://tomcat.apache.org/tomcat-9.0-doc/ssl-howto.html[Tomcat SSL instructions].
For example, if you use Tomcat, you should read the https://tomcat.apache.org/tomcat-10.1-doc/ssl-howto.html[Tomcat SSL instructions].
You should get this working before trying it out with Spring Security.
@@ -286,7 +286,7 @@ public class Config {
The code is invoked in the following order:
* Code in the `Config.configure` method is invoked
* Code in the `Config.filterChain` method is invoked
* Code in the `MyCustomDsl.init` method is invoked
* Code in the `MyCustomDsl.configure` method is invoked
@@ -241,16 +241,15 @@ fun rest(): RestTemplate {
val rest = RestTemplate()
rest.interceptors.add(ClientHttpRequestInterceptor { request, body, execution ->
val authentication: Authentication? = SecurityContextHolder.getContext().authentication
if (authentication != null) {
execution.execute(request, body)
if (authentication == null) {
return execution.execute(request, body)
}
if (authentication!!.credentials !is AbstractOAuth2Token) {
execution.execute(request, body)
if (authentication.credentials !is AbstractOAuth2Token) {
return execution.execute(request, body)
}
val token: AbstractOAuth2Token = authentication.credentials as AbstractOAuth2Token
request.headers.setBearerAuth(token.tokenValue)
request.headers.setBearerAuth(authentication.credentials.tokenValue)
execution.execute(request, body)
})
return rest
+1 -7
View File
@@ -1,6 +1,7 @@
plugins {
id 'org.antora' version '1.0.0'
id 'io.spring.antora.generate-antora-yml' version '0.0.1'
id 'io.spring.convention.repository'
}
apply plugin: 'io.spring.convention.docs'
@@ -59,10 +60,3 @@ def resolvedVersions(Configuration configuration) {
.resolvedArtifacts
.collectEntries { [(it.name + '-version'): it.moduleVersion.id.version] }
}
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/release' }
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
}
+4 -4
View File
@@ -1,11 +1,11 @@
aspectjVersion=1.9.19
reactorVersion=2022.0.9
aspectjVersion=1.9.20
reactorVersion=2022.0.10
springJavaformatVersion=0.0.39
springBootVersion=3.0.8
springFrameworkVersion=6.0.11
micrometerVersion=1.10.9
micrometerVersion=1.10.10
openSamlVersion=4.1.1
version=6.0.5-SNAPSHOT
version=6.0.6
kotlinVersion=1.7.22
samplesBranch=6.0.x
org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError