Add CORS support for Private Network Access

This commit adds CORS support for Private Network Access
by adding an Access-Control-Allow-Private-Network response
header when the preflight request is sent with an
Access-Control-Request-Private-Network header and that
Private Network Access has been enabled in the CORS
configuration.

See https://developer.chrome.com/blog/private-network-access-preflight/
for more details.

Closes gh-31974

(cherry picked from commit 318d460256)
This commit is contained in:
Sébastien Deleuze
2024-01-04 21:38:59 +01:00
parent dd9b6749d7
commit cfec88bfa8
18 changed files with 328 additions and 15 deletions

View File

@@ -131,6 +131,17 @@ public class CorsRegistration {
return this;
}
/**
* Whether private network access is supported.
* <p>Please, see {@link CorsConfiguration#setAllowPrivateNetwork(Boolean)} for details.
* <p>By default this is not set (i.e. private network access is not supported).
* @since 6.1.3
*/
public CorsRegistration allowPrivateNetwork(boolean allowPrivateNetwork) {
this.config.setAllowPrivateNetwork(allowPrivateNetwork);
return this;
}
/**
* Configure how long in seconds the response from a pre-flight request
* can be cached by clients.

View File

@@ -196,6 +196,7 @@ public abstract class AbstractHandlerMapping extends ApplicationObjectSupport
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
if (config != null) {
config.validateAllowCredentials();
config.validateAllowPrivateNetwork();
}
if (!this.corsProcessor.process(config, exchange) || CorsUtils.isPreFlightRequest(request)) {
return NO_OP_HANDLER;

View File

@@ -534,6 +534,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
if (corsConfig != null) {
corsConfig.validateAllowCredentials();
corsConfig.validateAllowPrivateNetwork();
this.corsLookup.put(handlerMethod, corsConfig);
}

View File

@@ -341,6 +341,18 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
"or an empty string (\"\"): current value is [" + allowCredentials + "]");
}
String allowPrivateNetwork = resolveCorsAnnotationValue(annotation.allowPrivateNetwork());
if ("true".equalsIgnoreCase(allowPrivateNetwork)) {
config.setAllowPrivateNetwork(true);
}
else if ("false".equalsIgnoreCase(allowPrivateNetwork)) {
config.setAllowPrivateNetwork(false);
}
else if (!allowPrivateNetwork.isEmpty()) {
throw new IllegalStateException("@CrossOrigin's allowPrivateNetwork value must be \"true\", \"false\", " +
"or an empty string (\"\"): current value is [" + allowPrivateNetwork + "]");
}
if (annotation.maxAge() >= 0) {
config.setMaxAge(annotation.maxAge());
}