CORS on ASP.NET Core Not Working
Overview
I feel like I am going crazy. I worked on this for most of the day yesterday and I just can't seem to fit the pieces together.
Here is my situation: I am trying to create a GraphQL API endpoint for my organization. I have been allowed to use all the new tools at my disposal so I am using ASP.NET Core for the backend since we are a Windows shop and want to use Windows authentication for all of our projects (this backend will be used for internal applications only). I feel like I have the most minimal Web API setup and CORS just will not work. If it matters, this project is targeting .NET Framework 4.7.2 since Oracle's data access library can't target .NET Core yet.
The Code
Program.cs is the default one created.
Here is Startup.cs. All I've added are the CORS bits, and some very basic GraphQL services. The CORS rules are as permissive as possible.
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services // to the container. public void ConfigureServices(IServiceCollection services) { services.AddMTSGraphQL(); services.AddCors(); services .AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } // This method gets called by the runtime. Use this method to configure the // HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseGraphiQl(); } else if (env.IsStaging()) { app.UseGraphiQl(); } app.UseCors(builder => builder .AllowCredentials() .AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod() ); app.UseMvc(); } }
I feel like the Windows authentication bit may play into this, so here are my web.config and launchSettings.json:
<?xml version="1.0" encoding="utf-8"?> <configuration> <location path="." inheritInChildApplications="false"> <system.webServer> <security> <authentication> <anonymousAuthentication enabled="false" /> <windowsAuthentication enabled="true" /> </authentication> </security> </system.webServer> </location> </configuration> { "$schema": "http://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": true, "anonymousAuthentication": false, "iisExpress": { "applicationUrl": "http://localhost:5000" } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "graphql/", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
On the frontend, I have a function that looks like this:
async function fetchData() { const response = await fetch("http://localhost:5000/graphql", { method: "post", credentials: "include", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query: ` { reports { id name url platform } } ` }) }); const data = await response.json(); return data; }
The Result
So, I run the ASP.NET Core application from Visual Studio using IIS Express. It runs on http://localhost:5000 and it exposes an endpoint named "graphql" as per the spec. Now, when I hit the endpoint with software like Insomnia, I get expected results. When I have NTLM authentication turned off, I get a 401. When I have NTLM auth turned on, I get data back. I get the same results when hitting the endpoint with curl (i.e., Invoke-WebRequest in Power Shell).
However, when I load up my frontend application on http://localhost:3000, the call does not work. The browser does its preflight request (according to the CORS spec), but fails with a 401 unauthorized error. This is expected I guess as part of NTLM authentication since it sends back the WWW-Authenticate header, but the browser does not respond to the challenge, even though I specify credentials: "include" in my fetch request.
What's more, if I try to do the preflight request manually with Invoke-WebRequest including credentials I get a 405 Method Not Allowed status. So it seems even if the browser was doing its job, it still may not work?
I am at a complete loss. Most of the StackOverflow questions I encountered were about how the questioner wasn't being permissive enough with their rules. As you can see, I've made them as permissive as possible. I've tried different AJAX solutions like axios, but they still don't seem to authenticate on the preflight request.
I'm kinda at my wit's end here. Typically with these problems I walk away for a day or two and come back with fresh eyes and figure it out. Yesterday was the third time I approached this problem and just can't seem to get it. Does anyone else have any ideas?
0 comments:
Post a Comment