CORS issue asp.net core web api. No 'Access-Control-Allow-Origin' header is present [closed] - asp.net-core

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I am using asp net core 2.1 and I have an account controller with following methods:
[HttpPost("login")]
public async Task<object> Login([FromBody] IdentityUserForLoginDto userForLogin)
{...}
[HttpPost("register")]
public async Task<object> Register([FromBody] IdentityClientForRegistrationDto userForRegistration)
{...}
When I fetch data on login method, everything works fine and user normally logs in, but when I try to register new user I get CORS issue:
Access to fetch at 'http://localhost:53531/api/account/register' from origin 'http://localhost:3001' has been blocked by CORS policy: 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.
and:
POST http://localhost:53531/api/account/register net::ERR_FAILED
In my backend I tried every possible combination of enabling CORS and for now I have this:
ConfigureServices:
services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
{
builder
.WithOrigins("http://localhost:3000", "http://localhost:3001")
.AllowAnyHeader().AllowCredentials()
.AllowAnyMethod();
}));
Configure
app.UseCors("ApiCorsPolicy");
Client-side data fetching:
fetch(`http://localhost:53531/api/account/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json'},
body: JSON.stringify(values)
})
.then(handleResponse)
.then(user => {
localStorage.setItem('currentUser', JSON.stringify(user));
currentUserSubject.next(user);
return user;
});
Both of them are placed before Add/UseMvc.
I've tried with AllowAnyOrigin, [EnableCors] etc..but always the same.
I want to point out that I've also tried with disabling cors from client but in that case I get text/plain media type and I explicitly want application/json.
Also, when I make the same request in postman everything works great..
Does anyone have any idea how to fix that issue?

I solved this. Problem was in data that was sent to server..it wasn't in format that server expected it to be

Related

Include custom WWW-Authenticate header in 401 Unauthorised response when using Microsoft.Identity.Web

Following instructions on making MS Office connect to my Asp.NET Core Web API, I am attempting to present a login redirect to MS Office for failed authentications. Following questions and answers I am attempting to include the login redirect information in the WWW-Authenticate header property. My Web API is protected with Azure AD and the Microsoft.Identity.Web library. When the authentication fails and the middleware returns the 401 Unauthorized response, the header does include the WWW-Authenticate property but it's value is only Bearer.
Q: How can update the header information to include the necessary additional redirect information?
I have tried to implement an attribute on the API, derived from IAsyncAuthorizationFilter and access the response header in that. However the middleware already returns a 401 before this attribute is called.
I have made progress by customizing the JwtBearerOptions configuration. However this approach creates an additional header item, instead of overwriting the standard value. As a result I have now 2 KeyValuePairs for the same key in the response header, which will likely have unexpected outcomes.
In my Startup.cs:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration)
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
var existingOnChallengeHandler = options.Events.OnChallenge;
options.Events.OnChallenge = async context =>
{
await existingOnChallengeHandler(context);
string headerInfo = context.Options.Challenge;
headerInfo += " resource=\"https://management.azure.com/\"";
context.Response.Headers.Append(HeaderNames.WWWAuthenticate, headerInfo);
};
});
The original answer put me on the right track. It turned out to be actually quite simple to do this once I knew to configure the JwtBearerOptions.Challenge property:
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Challenge = $"Bearer authorization_uri=\"{authorizationUri}\"";
}

CORS Error on Uno WebAssembly with ASP..NET Core REST API Service

I got these error on WebAssembly with Uno Platform.
Access to fetch at 'https://localhost:44318/api/search/bebek/TR' from
origin 'http://localhost:49917' has been blocked by CORS policy: 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.
I got some data responses as a JSON file from API service. The UWP app do it without error:
//_savedSearchList = await _dbService.SearchAsync(_keyword, _sentLanguageArgument); // Normal database connection for UWP.
//_savedSearchList = await _dbService.SearchAsync(_keyword, _sentLanguageArgument); // Normal database connection for UWP.
//Get search list for webservice.
var link_search = $"https://localhost:44318/api/search/{_keyword.ToLower()}/{_sentLanguageArgument}";
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(link_search);
Debug.WriteLine($"Http Status Code for Connection: {response.StatusCode}");
if (response.IsSuccessStatusCode)
{
var jsonString = await response.Content.ReadAsStringAsync();
_savedSearchList = JsonConvert.DeserializeObject<List<SearchResultCapsule>>(jsonString).OrderBy(t => t.IssueNumber);
if (_savedSearchList.Count() != 0)
{
ResultList.ItemsSource = _savedSearchList;
NoResult_Grid.Visibility = Visibility.Collapsed;
}
}
}
What is the real problem on WebAssembly ? And how can I fix it ? Thanks.
This is a security restriction from the Javascript fetch API, where the endpoint you're calling needs to provide CORS headers to work properly.
If you control the API, you'll need to use the features from your framework to enable CORS, and if you don't you'll need to ask the maintainers of the endpoint to enable CORS.
To test if CORS is really the issue, you can use CORS Anywhere to proxy the queries.
It solved via Microsoft CORS package. Thanks.

Response to preflight request doesn't pass access control check: It does not have HTTP ok status. GET working POST PUT DELETE not working

Greetings
I have one web application with following architecture:
Web api: ASP.net core 2.1 (Windows Authentication)
UI: angular 8
UI is able to get data but unable to send data.
I mean GET method is working fine but POST, PUT, DELETE options are not working .
And all the methods are working using POSTMAN.
ERROR is:
Access to XMLHttpRequest at 'http://xx.xxx.xxx.xx:xxyy/xxx/xxxxxx/Method' from origin 'http://localhost:xxxx' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Any help will be appreciated .
Thanks in advance :)
That's because your API is on different domain than your SPA angular application.
Please at this at the start of your Configure method in Startup.cs
if (env.IsDevelopment())
{
app.UseCors(opts =>
{
opts.WithOrigins(new string[]
{
"http://localhost:3000",
"http://localhost:3001"
// whatever domain/port u are using
});
opts.AllowAnyHeader();
opts.AllowAnyMethod();
opts.AllowCredentials();
});
}
Please note that this will handle only CORS for local development since you'll probably have same domain in production - if not, you'll need to reconfigure this for production also.
CORS blocking is browser specific and that's why it's working in PostMan but not in browser.
This is what i use and it should work i hope for your case.
My startup.cs ConfigureServices() decorated with:
services.AddCors(feature =>
feature.AddPolicy(
"CorsPolicy",
apiPolicy => apiPolicy
//.AllowAnyOrigin()
//.WithOrigins("http://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(host => true)
.AllowCredentials()
));
And, Configure() method with:
app.UseCors("CorsPolicy");
Notice the SetIsOriginAllowed() and allowCreds() along with other policy settings, this works for me with POST calls to my api from my angular, which are running on two different port#s.
UPDATE:
Following the questions on the comments, adding additional information on how do we check the logged in user (windows auth) btwn api and the angular (frontend).
You can check the incoming User on a specific route that would only expect the authenticated user using the decoration [Authorize]. In my case, i would have only one method that would expect the windows user in the api:
[HttpGet("UserInfo")]
[Authorize]
public IActionResult GetUserInfo()
{
string defaultCxtUser = HttpContext?.User?.Identity?.Name;
if (defaultCxtUser != null && !string.IsNullOrEmpty(defaultCxtUser))
{
_logger.LogDebug($"START - Get Context user details for {defaultCxtUser}");
ADHelper.logger = _logger;
var userFullName = ADHelper.GetUserIdentityInfo(defaultCxtUser);
_logger.LogInformation($"Context user {defaultCxtUser} with name: {userFullName}");
var userInfo = new { Name = userFullName };
//_logger.LogDebug($"END - GetUserInfo({defaultCxtUser} for {userFullName}");
return Ok(userInfo);
}
else
return Ok(new { Name = defaultCxtUser });
}
then i would call this from my angular with the service call as,
// Get the Logged in user info
GetCurrentUserInfo(): Observable<string> {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
}),
withCredentials: true
};
// return this.http.get<string>(`${ApiPath}UserInfo`, httpOptions)
// .pipe(map(v => v as string));
return this.http.get<UserInfo>(`${ApiPath}UserInfo`, httpOptions)
.pipe(map(data => {
// console.log(data, data.Name);
return data.Name;
}))
;
}
Please see the headers with 'withCredentials: true' line that would trigger to pass the current user info, and it would be read and understood only if it has the authorize attr to read the User.Identity object in c# side. The reason we do this on a specific method is that, there should be some other parental method in the api like ApiStatus() or anything that could be, should be called first. This would ensure to also invoke the preflight check with OPTIONS that would require anonymous auth. Like in my case, getting whether the api is available and running, and some other app environment info before i get the userInfo() from my angular app.

405 Response on post using axios in Vue 3.0 app to .Net Core 2.2 with AllowAnyMethod in policy

I am losing my mind and having read a lot of blogs, SO questions and documents I am sure it is a simple fix that I am now completely blind to.
I have an axios post call from a vuejs app to a .net core 2.2 api project. Following the Enable CORS guide from Microsoft I have used Access Policy in Services and decorated the controller. See the code below.
The pre-flight options response is 204 with a 405 response on the actual call citing allow: DELETE, GET, PUT as the permitted method ... what have I missed here? I have .AllowAnyMethod in the policy but it seems to be completely ignored. A colleague working with a WebAPI 2.2. project has the exact same code and it works.
StartUp.cs
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
options.AddPolicy("VueFrontEnd",
builder =>
{
builder.WithOrigins("http://localhost:30001/")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
Controller
[EnableCors("VueFrontEnd")]
[HttpPost]
public async Task<JsonResult> DoesItExist(string searchString)
{
var data = new string[] { "A", "B", "C" };
var result = data.Any(searchString.Contains);
return Json(JsonConvert.SerializeObject(result));
}
Vue
getClientsByPartialString(search: string) {
Axios({
method: 'post',
url: 'https://localhost:44380/api/values/DoesItExist',
crossDomain: true,
data: {
name: 'world',
},
})
}
This makes me sad. It was routing.
Adding [HttpPost("/TheApi")] decorator sorted it.
I am ashamed. I was using the full URL http://localhost:port/api/values/themethod and routing was failing me despite it being set on the controller.
The one thing that concerns me is why this worked with GET and PUT and ONLY failed on POST. I have no answer to that one.

JSONP - POST method in Sench Touch 2.1

With GET method, i easily get this reponse. But POST method i don't get it.
Ext.data.JsonP.request({
url: 'http://otherdomain/test_json_post',
method: 'POST',
type:'jsonp',
scope: this,
callbackkey: 'callback',
success: function(result) {
console.log(result);
//Your success function here...
}
});
What i wrong?
You cannot call any webservice from your browser because of security reasons so either you have to use JSONP proxy on app side or you have to enable CORS on your server side. If you are planning to build this as app then you don't have to do this, all you have to do is change security setting of your browser when you are testing. More details here : How to use json proxy to access remote services during development
Yes,it worked! ^^ Sencha Touch is a client-side(a Mobile Web App) or builded it localhost, it will have CORS - a browser policy security - related to your using ajax in it. So, I configed all api in my PHP server by add 2 code rows:
function yourAPI
{
//CORS open
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With');
....
{enter your code here}
}
Thank for Rob's help! Hope you have similar problem fix error successfully.