Skip to content

Consider supporting PreFlight requests and CORS in Servlet Functional Endpoints #24564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bclozel opened this issue Feb 21, 2020 · 5 comments
Closed
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@bclozel
Copy link
Member

bclozel commented Feb 21, 2020

Spring MVC supports CORS with simple and pre-flight requests.

Spring MVC provides support for global CORS handling with a filter, but also local support with @CorsMapping annotations or a CorsConfiguration instance, which is provided to AbstractHandlerMapping implementations.

In the case of Servlet Functional Endpoints, the provided CorsConfiguration has no effect on pre-flight requests.

Here is a sample application:

@Configuration
public class SampleRouterConfig {

	@Bean
	public RouterFunction<ServerResponse> router() {
		return RouterFunctions.route()
				.POST("/function", (req) -> ServerResponse.ok().body("Hello"))
				.build();
	}
}

We can also set a custom CorsConfiguration on the RouterFunctionMapping.

In this case, the following request will not match any handler, and other HandlerMapping later in the chain will handle this:

OPTIONS http://localhost:8080/function
Origin: https://spring.io
Access-Control-Request-Method: POST

Other HandlerMapping implementations have additional checks in the request matching infrastructure to check requests with CorstUtils.isPreFlightRequest(request). See implementations of AbstractRequestCondition and also AbstractHandlerMethodMapping itself.

I'm wondering if we should have here additional RequestPredicates to locally manage CORS requests, or if existing predicates should look for pre-flight requests and match anyway.

@poutsma
Copy link
Contributor

poutsma commented Mar 5, 2020

I was under the impression that since the RouterFunctionMapping extends from AbstractHandlerMapping, we get CORS for free? Is there more we can do?

@bclozel
Copy link
Member Author

bclozel commented Mar 5, 2020

We're getting most of it for free, expect for the pre-flight requests. We need in that case to match OPTIONS requests that qualify as pre-flight requests and make sure to match to the corresponding handler.

Could you take a look at AbstractRequestCondition and AbstractHandlerMethodMapping? In those classes we're making sure to match pre-flight requests. We might have to do something like this for RequestPredicates.

@rstoyanchev
Copy link
Contributor

rstoyanchev commented Mar 6, 2020

@poutsma, notice how RequestMethodsRequestCondition makes a special check for pre-flight requests. Rather than matching the actual method which is HTTP OPTIONS, it matches the HTTP method specified in the Access-Control-Request-Method header. This is necessary to ensure we can correctly identify that there is a match for the would-be, "actual" request.

From there AbstractHandlerMapping will use a PreFlightHandlerInterceptor to handle the request without ever calling the identified handler. The main purpose of finding that handler then was a) to ensure there is a match and b) to check if that handler implements CorsConfigurationSource. The latter could be used for example if the functional model added some equivalent to @CorsConfiguration for specific route(s) but it's not the only way.

One option could be to change the HTTP method of the request before trying to find a route. That would be an easy way to support course with RouterFunctionMapping. Another approach would be to consider the CORS support needed for route functions first, even if used independent of the HandlerMapping hierarchy.

@poutsma poutsma added this to the 5.2.5 milestone Mar 9, 2020
@poutsma
Copy link
Contributor

poutsma commented Mar 9, 2020

Thanks for the pointer, @rstoyanchev!

I think it should be possible to get this into the HttpMethodPredicate for 5.2.5.

@poutsma
Copy link
Contributor

poutsma commented Mar 10, 2020

Initial testing by @bclozel shows that there is more that needs to be done.

@poutsma poutsma reopened this Mar 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants