WebApi authentication failed on server with Angular - c#

I am using Asp.Net web API 2.0 with Angular 6 for UI. The solution contains the projects for angular and web API.
My solution works fine (I am able to access pages and login) when I am running it on Visual Studio on localhost. However when I deploy the build on server I am unable to login and getting the below error:
Access to XMLHttpRequest at 'http://xx.xx.xx.xxx:xxxxx/authenticate' from origin 'http://xx.xx.xx.xxx:xxxxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

To quickly handle CORS for Web API, add below settings in web.config file of Web API inside <system.webServer> section:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
But there is a security risk involved in enabling CORS. A good explanation is here.

Can you please add this following code to startup.cs -> configure()
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin().AllowCredentials());

Browser security prevents a web page from making AJAX requests to another domain. This restriction is called the same-origin policy and prevents a malicious site from reading sensitive data from another site. However, sometimes you might want to let other sites call your web API.
Install-Package Microsoft.AspNet.WebApi.Cors
Open the file App_Start/WebApiConfig.cs. Add the following code to the WebApiConfig.Register method: config.EnableCors();
Next, add the [EnableCors] attribute to the Controller class
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class TestController : ApiController
{
// Controller methods not shown...
}
Now you can access the API's

Related

Problem on CORS configuration with Web Api 2, OWIN and Identity Server

I have a few web applications under the same domain, all using a stand alone Identity Server 3 app for login purposes. Under test environment, every single one of then are under the same domain (http://192.168.100.1, or by dns http://companyServer).
Recently, one application needed to request some data from another app, and I found the following error when debugging on Visual Studio:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://companyServer:60000/MyApp/Api/Company/Info?parameter=123. (Reason: CORS header 'Access-Control-Allow-Origin' not present).
We have a central library responsible for configuring Web API on our systems, it has the following (among other things):
public static IAppBuilder UseCebiUtilWebApi(this IAppBuilder app, CebiWebApiOptions options)
{
Logger.Debug("Configuring Web API");
app.UseCors(CorsOptions.AllowAll);
...
}
On the same method, we also configure Identity Server.
I also checked on my Login Server App, and there is the following code regarding CORS:
public class CompanyCorsPolicyService : DefaultCorsPolicyService
{
public CompanyCorsPolicyService()
{
base.AllowAll = true;
}
}
This method is being called on the project's Startup.cs.
As far as I know, every single end of my environmet should be enabling full CORS access, no matter the origin. But the header is still missing.
I've tried quite a few solutions on the internet:
Using "config.EnableCors" instead of "app.UseCors"
Overriding GrantResourceOwnerCredentials,
I have also tried setting up manually some CORS related headers on Web.Config, but I was unable to find the specific question here on SO.
I don't think identity server is related to this problem, but since that is the difference between my evironment and the solutions I've found, I decided to put it in here too.
Any ideas?
It's possible that the OPTIONSVerbHandler could be intercepting all OPTIONS (CORS pre-flight) requests.
Try disabling that so that ASP.Net can handle those requests instead.

Only receiving HTTP requests in Google App Engine Flex with .NET. How to only allow HTTPS?

I have a website written in C# using ASP.NET Core MVC5 that I'm deploying onto Google Cloud App Engine Flex. I want to completely disable HTTP and only allow HTTPS. I do not want a redirect from HTTP to HTTPS. How do I go about doing this?
I tried searching and could not find any way to specify it in the app.yaml for .NET and App Engine Flex. So I tried to do it within the webserver code itself. At first as a test, I tried to use the RequireHttps attribute and I also tried an implementation of RequireHttpsOrClose (https://www.recaffeinate.co/post/enforce-https-aspnetcore-api/), which is closer to what I actually want.
When I built the projects and deploy via IIS (i.e. NOT google app engine), everything works fine. However, when I deploy to Google App Engine, they don't work right. When I try to connect to them, it always seems to come in as HTTP, even if the URL I use to connect is set as HTTPS. When I used the RequireHttps attribute, I got a "too many redirects" error, which tells me that it was taking my HTTPS request (e.g. "https://www.test.com") but within the controller, it was seeing it as if I had sent a plain HTTP request (e.g. like it was seeing "http://www.test.com" instead). So it again saw this as a supposed plain HTTP request (though it really wasn't) and attempted to redirect -- once again -- to an HTTPS request, which was again processed as a plain HTTP request. And this seems to continue infinitely, causing a redirect loop.
To test this further, I checked the value of Request.IsHttps, I ALWAYS got false even though I was definitely connecting with HTTPS. So for some reason the site is only receiving HTTP requests even though I'm requesting with HTTPS.
Again, when I test outside of App Engine (by deploying as via IIS on our non-Google web server), everything works perfectly. It is only when I deploy on App Engine that I get this weird behavior.
I can reproduce this by setting up a barebones project with "ASP.NET Core on Google Cloud Platform" template. The only relevant code is my controller, which is barebones and simply returns the dummy values supplied by the template:
[RequireHttps]
[Route("/")]
public class ValuesController : Controller
{
private readonly ILogger _logger;
public ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;
}
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
// When I remove the RequestHttps attribute in order to stop the redirect
// loop, I always get values "not https" and "HTTP/1.1" even though
// my browser is connecting to https://xxxxx.appspot.com
if (Request.IsHttps) return new string[] { "https", Request.Protocol };
return new string[] { "not https", Request.Protocol };
}
}
I publish this with an app.yaml of:
service: testservice
runtime: aspnetcore
env: flex
The web.config is unmodified from the project template:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>
So my questions are:
Why am I only receiving HTTP requests when I am definitely entering a HTTPS URL? Did I do something or set something in Google Cloud or in App Engine to cause this to happen?
Otherwise, is there some other method of disabling HTTP and only allowing HTTPS using App Engine Flex with .NET? All examples I could find of disabling it are for Python using handler in the app.yaml, but that doesn't seem to apply to .NET.
In the flexible environment you cannot use the app.yaml configuration to require HTTPS-only access, that can only be done in the standard environment. See related Correctly assign HTTPS only custom domain to flex env
From Request limits:
SSL connections are terminated at the load balancer. Traffic from the load balancer is sent to the instance over an encrypted channel,
and then forwarded to the application server over HTTP. The
X-Forwarded-Proto header lets you understand if the origin request was
HTTP or HTTPs.
This explains why you cannot use Request.IsHttps to identify if the request was HTTPS.
But you can modify that piece of logic to check the X-Forwarded-Proto instead which should get you what you need. I think it could be something along these lines (not 100% certain, I'm not a .NET user):
if (Request.Headers["X-Forwarded-Proto"] == "https") return new string[] { "https", Request.Protocol };
return new string[] { "not https", Request.Protocol };

ASP.NET MVC and Web Api in the same project, duplicate http response header values

I have a ASP.NET web project with a combination of both MVC 5 and Web Api 2. The project contains a web.config file with some custom http headers defined under the system.webserver section. These headers work fine for the MVC requests, but there are some duplicate values for the Api requests.
<customHeaders>
<clear />
<add name="Expires" value="-1" />
... other headers
</customHeaders>
All the API request have duplicate Http headers like Cache-Control, Expires and Pragma like this.
Cache-Control: no cache, no cache
Expires: -1,-1
It seems that the Web API Framework sets these values by default. Is it possible to disable the default Api headers and use the config settings or ignore the config settings at all for Api requests? Any thoughts for a good solution?
Clearing the customHeaders elements like above or override them by removing it first before adding doens't work either.
You can workaround this issue. Remove the customHeaders tag from web.config.
In your MVC 5 project, add a Custom Action Filter Attribute.
public class AddHeadersFilterAttribute: ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.AddHeader("header", "headerValue");
base.OnActionExecuting(filterContext);
}
}
Decorate your BaseController of your MVC 5 Controllers with this Attribute.
This should fix your issue and letting Web API 2 act like it should.

Is there a way to secure static files using owin?

I have a problem after implementing Owin and secured all controllers and webapi of a asp.net mvc site, using cookie and bearer token. All static files like javascripts , images and some html files are unsecured and can be downloaded without authorization.
So far I have tried to implement, staticfiles (using Microsoft.Owin.StaticFiles) and setting static files for a request path but without any sucess. For example this?
app.UseStaticFiles("/Scripts");
And I have tried , using web.config settings like this wich is mentiond in katana documentation, but from this point to lets say roleX should have access to imagesX and roleY to imageY ? nothing is mention in the documentation about that or even how to control the files.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
So question is how do i secure static files using owin and authorization cookie.
Do i have to write a own middle ware , checking each request if it is a static file, or is there any recomended package on nuget that solves this?
OWIN way of doing this would be with some middleware. New asp.net core will not support web.config and modules. Just be sure to plugin your auth middleware before static file middleware. It really depends what's your authentication and authorization framework of choice, but you can check an example here: https://coding.abel.nu/series/owin-authentication/

Can't refresh token, different origin

I have a web app that connects to my server side app.The web app gets the auth code while the server stores the tokens and refreshes the access tokens. When I issue api calls from localhost(both the web and server side parts are on the same domain) when my access tokens expire, I can normally refresh the tokens. When I deploy my code so that the web part is on domain A and the server api on domain B, refreshing the access tokens after expiration don't work. I guess it's an origin issue. I got web app keys from google console.
Does anyone know if there is a setting to enable cross origin for oauth?
Update: Maybe it doesn't have to do with cors. The problem is that I can run my app from localhost and not from my cloud deployed app.
I am assuming you are using ASP.NET WebApi 2.0? If so please refer to this article:
http://blog.rfaisal.com/2014/01/14/building-your-own-api-and-securing-it-with-oauth-2-0-in-asp-net-webapi-2/
Basically you need to:
Install this nuget package: Microsoft.AspNet.WebApi.Cors
In your WebApiConfig.Register method use the extension method EnableCors() on your HttpConfiguration object:
public static void Register(HttpConfiguration config)
{
config.EnableCors();
}
Decorate your controllers with this attribute:
[EnableCors(origins: "*", headers: "*", methods: "*")]
I hope this is useful!
There might be same-domain policy that is ruining your day because the schema is different.
Two pages are considered to be from the same origin if they have the same host, protocol and port.
From Wikipedia on the same origin policy:
The term "origin" is defined using the domain name, application layer
protocol, and (in most browsers) TCP port of the HTML document running
the script. Two resources are considered to be of the same origin if
and only if all these values are exactly the same.

Categories