I have a react app calling my service with CORS enabled from my local app. This works fine for GET methods but for some reason it throws a CORS exception when calling a POST method. Is there anything I need to add to configure for POST? thanks
in my startup.cs:
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins(
"http://localhost:3000"
);
});
});
In my react app the call is pretty basic:
axios({
method: "POST",
url: `https://localhost:44340/patientsearch`,
data: { searchModel },
});
The exception:
Access to XMLHttpRequest at 'https://localhost:44340/patientsearch' from origin 'http://localhost:3000' 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.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors(x =>
{
x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().WithOrigins("https://localhost:5002");
});
}
Related
I want to upload a .NET web API to a domain and then set the frontend to connect to it. The problem is I can't send requests to the API domain because of the same-origin policy. I tried to use CORS and allow all origins but because credentials are being sent through responses, I have to specify the exact domain that can connect to the API.
Here is the code I used in the my backend project:
app.UseCors(x => x
.WithOrigins("https://localhost:3000")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
and I get this error in my console when I try to log in:
Access to fetch at 'https://api.paykanpars.com/api/user/login' from origin 'http://localhost:3000' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
This works fine when I run the API on localhost but when I run it on my production host, it returns a 404 status in response to the preflight requests. The production host uses Plesk as its web host.
Try to use this syntax
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("AllowAnyOrigin",
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
.....
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
.....
// app.UseRouting();
app.UseCors("AllowAnyOrigin");
// app.UseAuthorization();
// app.UseEndpoints(..
}
Make sure that UseCors should be in the end of Configure method but before UseAuthorizaton. AddCors should be at the top of Configure services.
if only it works then you can replace
builder.AllowAnyOrigin()
with
builder.WithOrigins("https://localhost:3000")
I have 3 projects:
Client App
ASP.NET API App
IdentityServer4 MVC App
I am able to send a request from API to IDP but trying to send a request from Client to IDP yields
"CORS request made for path: /api/Trial/TrialAction from origin: https://localhost:44389 but
was ignored because path was not for an allowed IdentityServer CORS endpoint"
even though I added the following to the IDP:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", policyBuilder => policyBuilder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
and
// ...
app.UseRouting();
app.UseIdentityServer();
app.UseCors("CorsPolicy");
app.UseAuthorization();
// ...
The interesting part is, I can send a request from API to IDP without adding CORS configuration to IDP. What am I doing wrong?
Config.cs:
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email(),
};
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
{
new ApiResource("myapi",
"My API",
new [] { "membershipType" }
)
};
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
ClientId = "mywebclient",
ClientName = "My Web Client",
AllowedGrantTypes = GrantTypes.Code, // Authorization code flow with PKCE protection
RequireClientSecret = false, // Without client secret
RequirePkce = true,
RedirectUris = { "https://localhost:44389/authentication/login-callback" },
PostLogoutRedirectUris = { "https://localhost:44389/authentication/logout-callback" },
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"albidersapi"
},
AllowedCorsOrigins = { "https://localhost:44389" },
RequireConsent = false,
}
};
}
do yo have the client and API in the same project as IdentityServer? I typically recommend that you keep them apart.
A wild guess could be to swap these two lines:
app.UseIdentityServer();
app.UseCors("CorsPolicy");
Because apparently IdentityServer captures the request to the API?
The most likely issue is that your call from your client to your API is not including the access token.
The debug log is coming from this file here. If you look at where your debug statement is originating from you will see that it is checking if the path matches any within IdentityServerOptions.Cors.CorsPaths. Here is an image of what those paths generally are from a debug service I made.
These paths are just the default information and authentication endpoints for IdentityServer4. In other words it thinks your request is unauthenticated because it likely isn't including the access token.
If you are using IdentityServer4's template logging implementation with Serilog, then you can also add this to your appsettings.json to see what the ASP.NET Core CORS middleware has to say. It will be logging after IdentityServer4's log
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.AspNetCore.Authentication": "Debug",
"Microsoft.AspNetCore.Cors": "Information",
"System": "Warning"
}
}
}
Here is what my debug log looked like when I made a request to an endpoint with a proper CORS policy, but the request didn't include its access token.
[21:05:47 Debug] IdentityServer.Hosting.CorsPolicyProvider CORS request made for path: /api/v1.0/users/{guid}/organizations from origin: https://localhost:44459 but was ignored because path was not for an allowed IdentityServer CORS endpoint
[21:05:47 Information] Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware No CORS policy found for the specified request.
So it's not a CORS issue really. It's an access token or authentication issue. It is also possible, however, that your endpoint isn't being hit properly. However, you should be receiving a 404 on the client in addition to the log seen above.
I'm currently developing an Angular 8 Frontend & asp.net core 3.1 backend application where I use Azure AD to authenticate users.
The flow of the application goes as followed.
The user tries to login or access a route that is protected/guarded in my Angular app so the user gets redirected to the Azure login page. So now the Angular app has the required token to send along to my asp backend. My backend receives the token along with an API request. backend checks token & responds to the API call.
PROBLEM
When making the API call, I get redirected to the login page, but after logging in. I get
this error.
After I log in, I receive a valid token from azure via the URL: http://localhost:4200/#id_token=<< TOKEN >>
These are the headers from the request found in the network tab in my browser.
Not sure about this, but I don't see any tokens passed in those headers. Although I'm using HTTP INTERCEPTORS to add the token to my headers of each request. Can this be the problem?
MY CODE
Backend
Startup.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//other config services
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureActiveDirectory", options));
services.AddCors((opt =>
{
opt.AddPolicy("FrontEnd", builder => builder
.WithOrigins("http://localhost:4200")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
}));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//other configurations
app.UseAuthentication();
app.UseAuthorization();
app.UseCors("FrontEnd");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Simple API
[Route("api/[controller]")]
[ApiController]
[EnableCors("FrontEnd")]
[Authorize]
public class GezinnenController : ControllerBase
{
//Constructor & properties
// GET: api/Gezinnen
[HttpGet]
public async Task<ActionResult<IEnumerable<GezinForLijstDto>>> GetGezinnen()
{
var gezinnen = await _unitOfWork.GezinRepo.GetAllAsync(null, "Personen,Gemeente");
var gezinnenForLijstDto = _mapper.Map<IEnumerable<GezinForLijstDto>>(gezinnen);
return Ok(gezinnenForLijstDto);
}
Angular
App.module.ts
import { HttpClientModule, HTTP_INTERCEPTORS } from '#angular/common/http';
import { MsalModule, MsalInterceptor } from '#azure/msal-angular';
//other imports
export const protectedResourceMap:
[string, string[]][] = [['https://localhost:5001/api/gezinnen', ['api://<<API Client ID>>/api-access']] ];
#NgModule({
declarations: [
...
],
imports: [
...
MsalModule.forRoot({
clientID: '<<Frontend Client ID>>',
authority: 'https://login.microsoftonline.com/<<API tenant ID>>',
consentScopes: [ 'user.read', 'api://<<API Client ID>>/api-access' ],
protectedResourceMap: protectedResourceMap }),
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true
}],
bootstrap: [
AppComponent
]
})
export class AppModule { }
Can someone help me fix this? I'm starting to get desperate :-)
To resolve CORS error, In your startup.cs, Can you move app.UseCors("FrontEnd") above app.UseAuthentication()
Workround:
1.Modify the server to add the header Access-Control-Allow-Origin: * to enable cross-origin requests from anywhere (or specify a domain instead of *). This should solve your problem.
2.Using Angular proxy
For more details, you could refer to this article.
I have enabled CORS in my ASP.NET/Angular application by using AddCors and EnableCors in controllers. My application is communicating with AD B2C pages. After build I have this error in the console :
Access to XMLHttpRequest at 'https://XXX.b2clogin.com/ (redirected
from 'https://XXX.azurewebsites.net/User/Info') from origin
'https://XXX.azurewebsites.net' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
Startup.cs :
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
Controller :
[EnableCors("CorsPolicy")]
[Authorize]
public class UserEditController : Controller
I have enabled CORS on Azure too by putting : Allowed Origins - * .
UPDATE:
[Route("User/Info")]
[HttpGet]
public async Task<IActionResult> LoggedInUserInfo()
{
if (User.Identity.IsAuthenticated)
{
var user = ((ClaimsIdentity)User.Identity).FindFirst(ClaimTypes.NameIdentifier).Value;
var viewmodel = await userService.GetUserByObjectId(user);
return Json(new { loggedIn = "true", user = viewmodel });
}
return Json(new { loggedIn = "false" });
}
It appears that you're attempting a cross-origin request from the https://xxx.azurewebsites.net/ domain to the https://xxx.b2clogin.com/ domain.
Currently the .b2clogin.com domain doesn't allow any cross-origin requests from any other domain.
Very strange error I'm experiencing.
I have two methods in controller which are called by angular js http get event.
First one works fine, second one is throwing CORS error, not sure how is that possible since both of them are in same controller.
This is the error I'm getting:
These are the calls I'm doing in angularjs:
$http({
url: 'http://localhost:52876/api/Admin/GetLoanInfo',
method: "GET",
params: { loanID: querystringParam }
}).success(function (data, status) {
console.log(data);
$scope.LoanDetailsVM.LoanStatus = data.LoanStatus;
}).error(function (data, status) {
console.log(data);
});
$http({
url: 'http://localhost:52876/api/Admin/GetLoanCovenants',
method: "GET",
params: { loanID: querystringParam }
}).success(function (data, status) {
console.log(data);
}).error(function (data, status) {
console.log(data);
});
And the controller methods:
[HttpGet]
[Route("api/Admin/GetLoanInfo")]
public async Task<IHttpActionResult> GetLoanInfo(int loanID)
{
LoanApplication newApplication = null;
newApplication = db.LoanApplications.FirstOrDefault(s => s.LoanId == loanID);
return Ok(newApplication);
}
[HttpGet]
[Route("api/Admin/GetLoanCovenants")]
public async Task<IHttpActionResult> GetLoanCovenants(int loanID)
{
LoanCovenant newCovenant = null;
newCovenant = db.LoanCovenants.FirstOrDefault(s => s.LoanID == loanID);
return Ok(newCovenant);
}
I'm able to hit both methods, I have breakpoints in both of the methods, but not sure why is complaining about CORS on the first one.
Calling methods using CORS from a Web browser makes Web API being called first with an OPTIONS request (example at the end of this article).
This way, the browser knows if it can call the requested API.
In your case, the call to your endpoint seems to be crashing, which means the HTTP 500 error does not contain any CORS headers.
This explains why the web browser complaning about CORS HTTP Header missing: Reason: CORS Header 'Access-Control-Allow-Origin' missing.
If you fix your method, then HTTP OPTIONS should be ok, and the CORS erros would go away.