If an HTTP request is made to a CORS-enabled endpoint where an origin
HTTP request header is not specified, the request fails with an HTTP 500 error.
The exception in the logs is:
[2019-04-13 14:40:04Z] fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Endpoint MartinCostello.Api.Controllers.TimeController.Get (API) contains CORS metadata, but a middleware was not found that supports CORS.
Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code.
at Microsoft.AspNetCore.Routing.EndpointMiddleware.ThrowMissingCorsMiddlewareException(Endpoint endpoint)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.HttpOverrides.HttpMethodOverrideMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
However, app.Cors()
_has_ been added to the application before app.UseEndpoints(...)
.
This appears to have been introduced by #9181.
If the request has no origin
request header, then the CORS middleware is skipped:
However, the endpoint middleware finds the CORS metadata on the endpoint being invoked, and checks whether the CORS middleware was invoked (which it was, but was skipped as not needed) by looking for a key in the HttpContext
's items. The item isn't present, so an exception is thrown:
The key being tested by the endpoint middleware is only added if the origin
header is present in the request, which is here:
It would appear that two possible fixes are either:
HttpContext.Items
, or:origin
header if CORS metadata is present on the endpoint, and only throws the exception for the non-invocation of the CORS middleware if it is present in the HTTP request.[EnableCors(...)]
attribute to a controller method.The request succeeds if no origin
HTTP request header is provided.
.NET Core SDK (reflecting any global.json):
Version: 3.0.100-preview4-011204
Commit: 621575bab1
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-preview4-011204\
Host (useful for support):
Version: 3.0.0-preview4-27612-09
Commit: 64e9c3e1cd
Issue was found as part of making this commit to a simple sandbox app: https://github.com/martincostello/api/pull/109/commits/a40a99f2dbb82d17ce6cc7cde5e13bc400d78137
cc @pranavkm
For preview4, possible workarounds include:
1) Having a middleware that sets the value in HttpContext.Items
after UseCors()
```C#
app.UseCors();
app.Use((context, next) =>
{
context.Items["__CorsMiddlewareInvoked"] = true;
return next();
});
2) Disable the check in `EndpointRouting`:
```C#
services.AddRouting(r => r.SuppressCheckForUnhandledSecurityMetadata = true);
The first one would be preferred since it's not removing a check for a mis-configured application.
Most helpful comment
For preview4, possible workarounds include:
1) Having a middleware that sets the value in
HttpContext.Items
afterUseCors()
```C#
app.UseCors();
app.Use((context, next) =>
{
context.Items["__CorsMiddlewareInvoked"] = true;
return next();
});
The first one would be preferred since it's not removing a check for a mis-configured application.