DATAREST-1581 - Fixed CORS defaults to include all HTTP methods exposed by Spring Data REST.

The fix for DATAREST-1535 has changed the default allowed methods for CORS requests to a smaller set than we originally returned. This commit reinstantiates the default to be set to all HTTP methods, Spring Data repositories support by default.

Related tickets: DATAREST-1535.
This commit is contained in:
Oliver Drotbohm
2020-12-01 22:21:22 +01:00
parent 328ea26244
commit 38f2bc4598
4 changed files with 52 additions and 8 deletions

View File

@@ -28,10 +28,13 @@ import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.repository.support.Repositories;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.core.mapping.HttpMethods;
import org.springframework.data.rest.core.mapping.ResourceMappings;
import org.springframework.data.rest.core.mapping.ResourceMetadata;
import org.springframework.data.rest.webmvc.support.JpaHelper;
import org.springframework.data.util.ProxyUtils;
import org.springframework.data.util.Streamable;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.util.Assert;
@@ -58,6 +61,10 @@ import org.springframework.web.util.pattern.PathPatternParser;
*/
public class RepositoryRestHandlerMapping extends BasePathAwareHandlerMapping {
public static final HttpMethods DEFAULT_ALLOWED_METHODS = HttpMethods.none()
.and(HttpMethod.values())
.butWithout(HttpMethod.TRACE);
private static final PathPatternParser PARSER = new PathPatternParser();
static final String EFFECTIVE_LOOKUP_PATH_ATTRIBUTE = RepositoryRestHandlerMapping.class.getName()
+ ".EFFECTIVE_REPOSITORY_RESOURCE_LOOKUP_PATH";
@@ -361,7 +368,7 @@ public class RepositoryRestHandlerMapping extends BasePathAwareHandlerMapping {
config.addAllowedOrigin(resolveCorsAnnotationValue(origin));
}
for (RequestMethod method : annotation.methods()) {
for (HttpMethod method : getAllowedMethods(annotation)) {
config.addAllowedMethod(method.name());
}
@@ -392,5 +399,24 @@ public class RepositoryRestHandlerMapping extends BasePathAwareHandlerMapping {
private String resolveCorsAnnotationValue(String value) {
return this.embeddedValueResolver.resolveStringValue(value);
}
/**
* Returns the {@link HttpMethods} configured on the given annotation or the default methods to support.
*
* @param annotation must not be {@literal null}.
* @return
* @see #DEFAULT_ALLOWED_METHODS
*/
private static HttpMethods getAllowedMethods(CrossOrigin annotation) {
RequestMethod[] methods = annotation.methods();
return methods.length == 0
? DEFAULT_ALLOWED_METHODS
: HttpMethods.of(Streamable.of(methods)
.map(RequestMethod::name)
.map(HttpMethod::resolve)
.toList());
}
}
}

View File

@@ -64,7 +64,9 @@ public class RepositoryCorsConfigurationAccessorUnitTests {
assertThat(configuration.getAllowCredentials()).isNull();
assertThat(configuration.getAllowedHeaders()).contains("*");
assertThat(configuration.getAllowedOrigins()).contains("*");
assertThat(configuration.getAllowedMethods()).contains("HEAD", "GET", "POST");
assertThat(configuration.getAllowedMethods())
.contains("HEAD", "GET", "POST", "PUT", "PATCH", "OPTIONS")
.doesNotContain("TRACE");
assertThat(configuration.getMaxAge()).isEqualTo(1800L);
}