Issue authenticating Web api from MVC app - c#

I have MVC application and a Web Api hosted on different server. But i am not able to authenticate my web api's using ADFS if accessed from my mvc web app.
Getting "CORS Error"
Thanks in advance

You need to add Nuget Package Microsoft.ASP.Net.Cors and add [EnableCors("", "", "*")] attribute to your controller class
[EnableCors("*", "*", "*")]
public class YourController : ApiController
{
}
Add this in WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.EnableCors();
}
You may check this Link.

Please do not add a CORS filter with "*" (wild cards to allow any IP/Domain..).
Owasp's Cheat Sheet has some handy pointers and further information: https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Cross_Origin_Resource_Sharing

Related

Getting 'Access-Control-Allow-Origin' error when I call External WebApi

I found a lot of pages regards to this issue, but none of the Solutions worked.
I have a JavaScript Button in the View that is calling a WebApi method(C#)
$('#btn-Sign-in', this).click(function () {
var apiUrl = 'https://localhost:44391/api/test';
fetch(apiUrl).then(response => {
return response.json();
}).then(data => {
// Work with JSON data here
console.log(data);
}).catch(err => {
// Do something for an error here
});
});
This is My Webapi method that is calling external api:
[RoutePrefix("api")]
public class TestController : ApiBaseController
{
[HttpGet]
[Route("redirectforauth")]
[RequiresPermission("Home:View")]
[HttpGet]
[Route("test")]
[RequiresPermission("Home:View")]
public async Task<IHttpActionResult> ConnectExternal()
{
var request = new FlurlRequest("URL of an external website")
.SetQueryParam(...)
.SetQueryParam(...)
.SetQueryParam(...)
.SetQueryParam(...);
var redirectUrl = request.Url.ToInvariantString();
return Redirect(redirectUrl);
}
when I am running the project, I am getting this error:
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.
This error is due to your web application URL & C# API URL are not having same origins (not running on same port or same hosts). Two URLs have the same origin if they have identical schemes, hosts, and ports.
EX: Your C# URL https://localhost:44391 is different from your web application URL.
First, to make sure that you are getting the error due to your c# api & not due to the external api, comment out your external api request code inside your action, and return something directly from your api to web application. (If the error is from external Api, that external api needs to handle this to allow access to other origins.)
If you are getting the error due to your c# api & not due to the external api, one approach to do this is, by enabling CORS in your C# WebApi application. You can enable CORS per action, per controller, or globally for all Web API controllers in your application.
You can install this nuget package in your C# API application:
Microsoft.AspNet.WebApi.Cors
In App_Start/WebApiConfig.cs, add this code to the WebApiConfig.Register method:
config.EnableCors();
Next, add the [EnableCors] attribute to your TestController class, with your web application URL.
Ex: if your web application URL is localhost:3000, add it in origins as below.
[EnableCors(origins: "http://localhost:3000", headers: "*", methods: "*")]
public class YourController : ApiController {
// Your methods...
}
Now the AJAX request from your Web Client should work. The GET, PUT, and POST methods are all allowed.
For more details on how to enable CORS & how it works:
Enable cross-origin requests in ASP.NET Web API 2

ASP.NET Core MVC Web API deployment issues

I'm trying to deploy my ASP.NET Core MVC Web App with Web API, i.e. I have both MVC and API controllers in the same folder.
It works fine on localhost but on IIS when I create a Virtual Directory, the path gets added to the domain.
I can find it using window.location.pathname
I can append the 'api/Get' and it works like (questions is my virtual directory)
http://example.com/questions/api/Question/GetAll
But when I navigate to other pages then then controller name also gets appended and then it causes issues.
e.g. if I navigate to the 'Question' page (QuestionController), the URL becomes
http://example.com/questions/newquestion/api/Question/Create
instead of
http://example.com/questions/api/Question/Create
How can I fix it?
Here is my Asp.Net core api.
[ApiController]
public class ScheduleController : ControllerBase
{
[HttpGet]
public List<PathologistSchedule> GetPathologistScheduleByDate(DateTime taskDate)
{
return pathologistRepository.GetPathologistScheduleByDate(taskDate).ToList();
}
}
I call this api from PathologistScheduleController's view using jquery.
Here's the error I get:
GET http://localhost:51434/PathologistSchedule/api/Schedule/?sort=&group=&filter=&taskDate=2020-11-13T21%3A16%3A47.507Z 404 (Not Found)
TIA.
A
If you have API and MVC projects in one solution you have to config your solution to run multiple projects.
You can use route attribute like this for each of your APIs
[Route("~/api/Question/GetAll")]
will give you Url http://example.com/api/Question/GetAll.
Or
[Route("~/api/Question/Create")]
will give Url http://example.com/api/Question/Create.
And it will not depend on the controller name or folder.
UPDATE because of the question update:
Use this code please:
public class ScheduleController : ControllerBase
{
[Route("~/api/Schedule/GetPathologistScheduleByDate/{taskDate?}")]
public List<PathologistSchedule> GetPathologistScheduleByDate(DateTime taskDate)
{
return pathologistRepository.GetPathologistScheduleByDate(taskDate).ToList();
}
}
for testing try this route in your browser:
http://localhost:51434/api/Schedule/GetPathologistScheduleByDate/2020-11-13T21%3A16%3A47.507Z
But basically for APIs you don't need to use any controller or action name. You can use any names you like, for example:
[Route("~/api/Pathologist/GetSchedule/{taskDate?}")]
or
[Route("~/api/GetPathologistSchedule/{taskDate?}")]
or even
[Route("~/api/{taskDate?}")]
The route just should be unique.
I added a variable in the 'appsettings.json' and 'appsettings.Development.json' called baseURL and had 'appsettings.json' set to '/VirtualDirectoryName/' and kept the one in 'appsettings.Development.json' as '/'.
Appended this variable when calling APIs.

IntegrationTest controllers with .net core 2.0 on web api

I've just created an empty web api project with .net core 2.0.
I have a default controller and I want now create an integration test.
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
The goal is self host in the integration then enter url api/values and check the return.
NB: I only use wep api 2 and owin, and it was quite easy to do this. But the following link: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/owin says that .net core application should not use owin, so what should we use and how to it?
Take a look at the official documentation for integration testing with ASP.NET Core 2.0: https://learn.microsoft.com/en-us/aspnet/core/testing/integration-testing
The main idea is to create a TestServer instance with a WebHostBuilder configured with your Startup class. You can then get a HttpClient instance from the TestServer to call your self-hosted api

"Method Not Allowed(#405 status code)" While Putting Data on Web api from Console Application in C#

I am working on Console Application and, I am calling a web API from console application to put data onto the web API but when I am getting the data using GetAsync() method I am able to get the data and when I am putting the data also able to put data while the web API is not hosted on IIS
After hosting on IIS I got the status code 405 "Method not allowed"
I have also tried enabling cors inside web API config in a register()
config.EnableCors();
and
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class ValuesController : ApiController
Any help will be Appreciated.
Thanks
I was putting the data onto Web API using PutJsonAsAsync(), but It doesn't work with PutJsonAsAsync() I don't know why but when I used PostAsJsonAsync() it works for me.
thanks

Web API CORS FormsAuthentication from AngularJS Client

I Implemented an AngularJS Project. The Server Side I coded using .NET Web API (C#). I Enabled the CORS in the Web API by installing the NuGet Package https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Cors
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class SampleController : ApiController
{
[AllowAnonymous]
[HttpGet]
public string GetAnonymousString()
{
FormsAuthentication.SetAuthCookie("Sample AllowAnonymous", false);
return "Calling AllowAnonymous Method using CORS - Public Text";
}
[Authorize]
[HttpGet]
public string GetAuthorizeString()
{
return "Calling Authorize Method using CORS - Private Text";
}
}
I hosted the client Side Application in http://localhost:8050 and I hosted Service Web API in http://localhost:8060.
Now I tried to access the GetAnonymousString() - http://localhost:8060/api/Sample/GetAnonymousString its working fine and also it returns the httponly cookie to the client via response.
But I tried the same for GetAuthorizeString() - http://localhost:8060/api/Sample/GetAuthorizeString, it returns 401 Unauthorized error as a response.
If I hosted Client App and Web API in the same domain, then its working fine. Only issue is CORS.
Kindly assist me how to use the Authorize in CORS ???

Categories