cors-error although endpoint exists in policy - asp.net-core

I have a pretty simple ASP.NET core-webapi that I'm trying to access from my client. The client is running on http://localhost:3000, while my server is running on https//localhost:7156. So I added a policy to accept requests from localhost:3000:
my Program.cs:
var builder = WebApplication.CreateBuilder(args);
// basic otel instrumentalisation
builder.Services.AddOpenTelemetryTracing(svc =>
{
svc.AddSource(new[] { nameof(ServiceController), nameof(StressTestController), nameof(BoundaryPointsController), nameof(AaaServiceClient) }).
SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(serviceName: svcName, serviceVersion: svcVersion)).
AddHttpClientInstrumentation().
AddAspNetCoreInstrumentation();
}).AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("https://localhost:3000",
"http://localhost:3000",
"localhost:3000");
});
});
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.Run();
my controller:
[EnableCors]
[ApiController]
[Route("api/projectdb/[action]")]
public class LoadDataController : ControllerBase
{
[HttpPost, ActionName("load")]
public async Task<ActionResult> LoadData() { ... }
}
When I perform the request from my client I get CORS-error:
const response = await fetch(`https://localhost:7156/api/projectdb/load`, {
method: 'POST',
body: '{ }',
headers: {'Content-Type': 'application/json; charset=UTF-8'}
});
This is the error I get:
Access to fetch at 'https://localhost:7156/api/projectdb/load' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

The error message is on point: because of the value of your request's Content-Type header, you need to explicitly allow that header in your CORS configuration:
// -snip-
.AddCors(options =>
options.AddDefaultPolicy(builder =>
builder.WithOrigins("http://localhost:3000")
.WithHeaders("Content-Type");
)
);

Related

Blazor server, call api controller delete/{filename} to delete file. 404 response

I have an api that works in most functions, but not on my HttpDelete where I got 404 response.
[Route("/[controller]")]
[ApiController]
public class UploadController : ControllerBase
..
[HttpDelete("delete/{filename}")]
public IActionResult Delete(string filename)
{
try
{
var filePath = Path.Combine(grundPath, ulPath, filename);
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
return StatusCode(200);
}
}
catch (Exception ex)
{
return StatusCode(500, ex.Message);
}
return StatusCode(500);
}
My Blazor component :
..
#inject HttpClient Http
..
string url = $"delete/{filename}"
HttpResponseMessage response = await Http.DeleteAsync(url);
..
I have tried to set url = $"https://localhost:XXXX/delete..... but same result.
Filename are in form "picture.png"
StatusCode: 404, ReasonPhrase: 'Not Found', Version: 1.1, Content:
System.Net.Http.HttpConnectionResponse Content, Headers: { Set-Cookie:
x-ms-gateway-slice=estsfd; path=/; secure; httponly DATE...
I'm a newbie on api controller so I have no clue what I missed. Don't even know where to start google...
[EDIT : Added Swagger to project]
After analysed with Swagger, I got this in swagger :
[DELETE] /delete/{filename}
Added a filename and execute, got this requested url :
https://localhost:7285/delete/_eskilssk%C3%A4rmklipp.PNG
And the file are deleted. So far so good.
Change / added code to this :
string filename = WebUtility.UrlEncode(fil.Namn);
string baseUrl = $"https://localhost:7285/delete/{filename}";
await JsRuntime.ToastrSuccess("Info : " + baseUrl);
HttpResponseMessage response = await Http.DeleteAsync(baseUrl);
My Toastr gives me :
https://localhost:7285/delete/_eskilssk%C3%A4rmklipp.PNG
same as swagger...
But this in my output i Visual studio :
System.Net.Http.HttpClient.Default.LogicalHandler: Information: Start
processing HTTP request DELETE
https://localhost:7285/delete/_eskilsskärmklipp.PNG
System.Net.Http.HttpClient.Default.ClientHandler: Information: Sending
HTTP request DELETE
https://localhost:7285/delete/_eskilsskärmklipp.PNG
Could it be my encoding that's wrong?
My Program.cs, maybe wrong order?
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllersWithViews()
.AddMicrosoftIdentityUI();
builder.Services.AddRazorPages();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
options.AddPolicy("Admin", policy => policy.RequireClaim("role", "Admin"));
});
builder.Services.AddAutoMapper(typeof(Program));
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
}, ServiceLifetime.Transient);
builder.Services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
builder.Services.AddScoped<>(); // Some repositories
..
builder.Services.AddScoped<DialogService>();
builder.Services.AddScoped<NotificationService>();
builder.Services.AddScoped<TooltipService>();
builder.Services.AddScoped<ContextMenuService>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseDeveloperExceptionPage(); // Remove when publish!!!
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.MapDefaultControllerRoute();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Blazor API V1");
});
app.Run();
2022-11-10
Problem found, when I comment out // app.UseAuthentication and app.UseAuthorization I could reach the API from my component. It's a security problem and doesn't have anything to do with this original question.
Start a new question with more correct information.
Blazor server and API in same project, 404 not found when app.UserAuth is activate
In ASP.NET Core, the action's route is : [controller]/[action]. In your case :
/upload/delete/{filename}
The client need to call this url like :
..
#inject HttpClient Http
..
string url = $"upload/delete/{filename}"
HttpResponseMessage response = await Http.DeleteAsync(url);
..
If you want the action's url is delete/{filename}, then you can start the action route segment by /. ASP.NET Core MVC will ignore the controller route segment when the action route segment start by / like :
[HttpDelete("/delete/{filename}")]
public IActionResult Delete(string filename)

How to resolve Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' ... in ASP.NET 5

I am trying to add Google authentication to my website which is been developed using ASP.NET 5 with web API controller along with react and axios. The request call from axios is throwing Network error. As shown below
Error: Network Error
at createError (https://localhost:44331/static/js/bundle.js:48536:15)
at XMLHttpRequest.handleError (https://localhost:44331/static/js/bundle.js:47921:14)
message: "Network Error"
isAxiosError: true
When I check the browser console it throws error stating --> Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=610964943445-9jinqs228qqa64kt9fqdsmo1mtkbg9ni.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Flocalhost%3A44331%2Fsignin-google&scope=openid%20profile%20email&state=CfDJ8If3moGK8nFOrHvENOPET4upw6kmRMdILweas1dhbMn4xPQuR1iRNG_YyZmLF5U-1BGJAYpW2XDf_38k7Glu2UGC2MGe4lEP3G1kUm4FhQ39A4Cw3Mq9G3W4E9t7xJltqSWiDuNdu-MyJr39ykiFRYMziYWVcIhf9J-Ju6R4LlqQKpw5WL2BV2s84_vl8l1z1TCH2QX0Ifz6XPlEdpqK3G6MqI8OFsjMd96RimTzZIL00Q3Bkeb6JOpMl5TWoP3lRYPsR0sf2vEVnX1xYxoGFU0'
(redirected from 'https://localhost:44331/signin/ExternalLogin?provider=Google') from origin 'https://localhost:44331' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Below are my code details-->
Startup.cs-->
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication().AddGoogle(googleOptions =>
{
googleOptions.ClientId = configuration.Google.ClientId;
googleOptions.ClientSecret = configuration.Google.ClientSecret;
});
services.AddCors(options => options.AddPolicy("MyPolicy",
builder =>
{
builder
.WithOrigins("https://localhost:44331")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
}));
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddControllers();
services.AddMvc();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
..
app.UseRouting();
app.UseAuthentication();
app.UseCors("MyPolicy");
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
SignInController.cs-->
[ApiController]
[Route("[controller]/[action]")]
public class SignInController : ControllerBase
{
...
[EnableCors("MyPolicy")]
[AllowAnonymous]
[HttpPost]
public IActionResult ExternalLogin(string provider, string returnUrl=null)
{
var redirectUrl = Url.Action("ExternalLoginCallback", "SignIn",
new { ReturnUrl = returnUrl });
var properties = _signInManager
.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return new ChallengeResult(provider, properties);
}
}
reactapicall.jsx-->
import axios from "axios";
const baseUrl = "/signin/"
export default {
login(url = baseUrl) {
return {
gmail: providerName => axios.post(url + "ExternalLogin?provider=" + providerName, null, { headers: { 'content-type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': '*'} })
}
}
}
launchSettings.json-->
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "https://localhost:44331",
"sslPort": 44331
}
package.json-->
{
"name": "best_ui_react_app",
"version": "0.1.0",
"private": true,
"proxy": "https://localhost:44331",
"dependencies": {
"#emotion/react": "^11.4.1"
}
..
}
I have tried all the approaches but none of them worked. Please give me some suggestions so that I can fix this issue.

Cannot call DELETE webapi method due to 405 Http status code

I have written API with .NET Core 3.0 Preview, and using Angular 8 for frontend.
I have one method on User controller called DeleteUser. This is the method:
//DELETE users/d18da620-6e4d-4b1c-a1ec-36d89145f4ca
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteUser(Guid id) {
...
}
So, when request is performed with Angular like this:
this.usersApiService.deleteUser(userId).subscribe((data) => {
...
}
After this call is performed, I get following output in Visual Studio:
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executing endpoint '405 HTTP Method Not Supported'
However, I've set custom CORS policy. In ConfigureServices I have this:
services.AddCors(options => {
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowed((host) => true)
.AllowAnyHeader());
});
and in Configure method, I use this policy:
app.UseCors("CorsPolicy");
So my question is, how to successfuly call this delete method? What am I missing?
Edit: This is my deleteUser method that calls api
public deleteUser(userId) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type' : 'application/json'
}),
body: {
id: userId
}
};
return this.httpClient.delete(this.USERSENDPOINT, httpOptions);
}
Update:
Try to call your method in angular like this:
this.httpClient.delete(this.USERSENDPOINT+"/"+userId);
hope it helps

CORS error with Aurelia calling .NET core API 2.0

I am getting a CORS error and I don't know how to fix it. I have an Aurelia app, calling a .NET core 2.0 API using aurelia-fetch-client. I am getting the following error:
Failed to load http://localhost:58289/api/info: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
TypeError: Failed to fetch
at applyInterceptors (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:428:14)
at processResponse (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:411:10)
at eval (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:299:14)
From previous event:
at HttpClient.eval (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:287:61)
at HttpClient.fetch (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:273:21)
at App.callApi (webpack-internal:///app:42:25)
at CallScope.evaluate (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:1578:19)
at Listener.callSource (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:5279:40)
at Listener.handleEvent (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:5288:10)
at HTMLDocument.handleDelegatedEvent (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:3363:20)
Please find my code below.
aurelia-fetch-client configuration:
const http = new HttpClient().configure(config => {
config
.withBaseUrl(environment.apiBaseUrl)
.withDefaults({
headers: {
'Content-Type': 'application/json'
}
})
.withInterceptor({
request(request: Request) {
var token = localStorage.getItem('access_token')
request.headers.append('Authorization', 'Bearer ' + token)
return request;
},
responseError(error){
return error;
}
});
});
aurelia.container.registerInstance(HttpClient, http);
Call the API:
callApi(){
this.httpClient.fetch("/info")
.then(response => console.log(response));
}
API startup configuration:
public void ConfigureServices(IServiceCollection services)
{
string domain = $"https://{Configuration["Auth0:Domain"]}/";
var allowedCors = Configuration["CorsSite"];
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = domain;
options.Audience = Configuration["Auth0:ApiIdentifier"];
});
services.AddCors(options => options.AddPolicy("AllowSpecificOrigin", `builder => {`
builder.AllowAnyOrigin().AllowAnyMethod(); }));
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("AllowSpecificOrigin");
app.UseAuthentication();
app.UseMvc();
}
Controller:
[Produces("application/json")]
[Route("api")]
public class InfoController : Controller
{
// GET api/values
[HttpGet]
[Route("Info")]
public IActionResult Get()
{
return Ok("Api V1.0");
}
[Route("authorizedInfo")]
[Authorize]
[HttpGet]
public IActionResult GetAuthorized()
{
return Ok("Authorized Api V1.0");
}
}
Please ignore the authorisation bit for now. I am only trying to hit the unauthorised API endpoint in localhost, but I am stuck. How can I fix my problem?
To do this start with registering CORS functionality in ConfigureServices() of Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// Add service and create Policy with options
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials() );
});
services.AddMvc();
}
The AddCors() call above adds the CORS features to ASP.NET and creates a custom policy that can be reused in the application by name. There are other ways to do essentially the same thing by explicitly adding a policy builder in the configuration step but to me this seems cleanest - define one or more policies up front and then apply it.
Once the policy has been defined it can be applied.
You can apply the policy globally to every request in the application by call app.useCors() in the Configure() method of Startup:
public void Configure(IApplicationBuilder app)
{
// ...
// global policy - assign here or on each controller
app.UseCors("CorsPolicy");
// ...
// IMPORTANT: Make sure UseCors() is called BEFORE this
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
or you can apply the policy to individual controllers:
[EnableCors("CorsPolicy")]
[ApiExceptionFilter]
public class AlbumViewerApiController : Controller
Thank You
The answer in the following link fixed my issue.
Web API 2 CORS IIS Express Debug and No Access-Control-Allow-Origin header
It appears that if there is no origin header in the request the server will not respond with the corresponding Access-Control-Allow-Origin response. Also with aurelia-fetch-client defaults I would have expected to have the origin header added by default.

How to get the headers from HTTP response when using http.post [duplicate]

I'm triggering a HTTP request and I'm getting a valid response from it. The response also has a header X-Token that I wish to read. I'm trying the below code to read the headers, however, I get null as a result
this.currentlyExecuting.request = this.http.request(reqParams.type, reqParams.url, {
body: reqParams.body,
responseType: 'json',
observe: 'response'
}).subscribe(
(_response: any) => {
// Also tried _response.headers.init();
const header = _response.headers.get('X-Token');
console.log(header);
onComplete(_response.body);
},
_error => {
onComplete({
code: -1,
message: Constants.WEBSERVICE_INTERNET_NOT_CONNNECTED
});
}
);
The response of the API, when checked in Chrome inspect, shows the header is present.
Have you exposed the X-Token from server side using access-control-expose-headers? because not all headers are allowed to be accessed from the client side, you need to expose them from the server side
Also in your frontend, you can use new HTTP module to get a full response using {observe: 'response'} like
http
.get<any>('url', {observe: 'response'})
.subscribe(resp => {
console.log(resp.headers.get('X-Token'));
});
In my case in the POST response I want to have the authorization header because I was having the JWT Token in it.
So what I read from this post is the header I we want should be added as an Expose Header from the back-end.
So what I did was added the Authorization header to my Exposed Header like this in my filter class.
response.addHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader("Access-Control-Allow-Headers", "Authorization, X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept, X-Custom-header");
response.addHeader(HEADER_STRING, TOKEN_PREFIX + token); // HEADER_STRING == Authorization
And at my Angular Side
In the Component.
this.authenticationService.login(this.f.email.value, this.f.password.value)
.pipe(first())
.subscribe(
(data: HttpResponse<any>) => {
console.log(data.headers.get('authorization'));
},
error => {
this.loading = false;
});
At my Service Side.
return this.http.post<any>(Constants.BASE_URL + 'login', {username: username, password: password},
{observe: 'response' as 'body'})
.pipe(map(user => {
return user;
}));
You should use the new HttpClient. You can find more information here.
http
.get<any>('url', {observe: 'response'})
.subscribe(resp => {
console.log(resp.headers.get('X-Token'));
});
As Hrishikesh Kale has explained we need to pass the Access-Control-Expose-Headers.
Here how we can do it in the WebAPI/MVC environment:
protected void Application_BeginRequest()
{
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "TestHeaderToExpose");
HttpContext.Current.Response.End();
}
}
Another way is we can add code as below in the webApiconfig.cs file.
config.EnableCors(new EnableCorsAttribute("", headers: "", methods: "*",exposedHeaders: "TestHeaderToExpose") { SupportsCredentials = true });
**We can add custom headers in the web.config file as below. *
<httpProtocol>
<customHeaders>
<add name="Access-Control-Expose-Headers" value="TestHeaderToExpose" />
</customHeaders>
</httpProtocol>
we can create an attribute and decore the method with the attribute.
Happy Coding !!
You can get data from post response Headers in this way (Angular 6):
import { HttpClient, HttpHeaders, HttpResponse } from '#angular/common/http';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
observe: 'response' as 'response'
};
this.http.post(link,body,httpOptions).subscribe((res: HttpResponse<any>) => {
console.log(res.headers.get('token-key-name'));
})
You can get headers using below code
let main_headers = {}
this.http.post(url,
{email: this.username, password: this.password},
{'headers' : new HttpHeaders ({'Content-Type' : 'application/json'}), 'responseType': 'text', observe:'response'})
.subscribe(response => {
const keys = response.headers.keys();
let headers = keys.map(key => {
`${key}: ${response.headers.get(key)}`
main_headers[key] = response.headers.get(key)
}
);
});
later we can get the required header form the json object.
header_list['X-Token']
Angular 7
Service:
this.http.post(environment.urlRest + '/my-operation',body, { headers: headers, observe: 'response'});
Component:
this.myService.myfunction().subscribe(
(res: HttpResponse) => {
console.log(res.headers.get('x-token'));
} ,
error =>{
})
Try this simple code.
1. Components side code: to get both body and header property. Here there's a token in body and Authorization in the header.
loginUser() {
this.userService.loginTest(this.loginCred).
subscribe(res => {
let output1 = res;
console.log(output1.body.token);
console.log(output1.headers.get('Authorization'));
})
}
2. Service side code: sending login data in the body and observe the response in Observable any which be subscribed in the component side.
loginTest(loginCred: LoginParams): Observable<any> {
const header1= {'Content-Type':'application/json',};
const body = JSON.stringify(loginCred);
return this.http.post<any>(this.baseURL+'signin',body,{
headers: header1,
observe: 'response',
responseType: 'json'
});
}
I had to do the following to get the headers to appear in SPA Angular application when GETting them from ASP.NET Core service:
var builder = WebApplication.CreateBuilder(args);
services.AddCors(options =>
{
options.AddPolicy("MyExposeResponseHeadersPolicy",
builder =>
{
builder.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
});
});
builder.Services.AddControllers();
var app = builder.Build();