Can't refresh token, different origin - c#

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.

Related

Self-hosted SignalR in Windows .Net Service blocked by CORS on same server, works on other servers

I've been using a Self-Hosted SignalR Windows service accessed from multiple production servers (now in Azure) for 6+ years without a problem. I created an identical server for development in Azure but when I'm accessing SignalR from a browser on the SAME SERVER, SignalR gives me the following error when using either http:6287 or https:6286:
Access to XMLHttpRequest at 'http://myserver.learn.net:6287/signalr/negotiate?clientProtocol=1.5&xxxxxxx' from origin 'http://myserver.learn.net' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
However... It WORKS when connecting from OTHER SERVERS! I'm starting the connection with no errors using:
SignalR = WebApp.Start("http://myserver.learn.net:6287/");
SignalRSSL = WebApp.Start("https://myserver.learn.net:6286/");
(also SignalR = WebApp.Start("*:628x/" for both);
In my client code, I include the following script:
<script src="http://myserver.learn.net:6287/signalr/hubs"></script>
When I enter that url (or https version) in a browser ON THE SAME OR DIFFERENT SERVER, it shows the ASP.NET SignalR JavaScript Library v2.3.0-rtm page correctly! I've turned off the firewall with no change, added Microsoft.Owin.Host.HttpListener (someone suggested). I have also entered the wildcard certificate with netsh so the SignalR service can deal with the SSL connection using:
netsh http add sslcert ipport=0.0.0.0:6286 appid={12345678-db90-4b66-8b01-88f7af2e36bf} certhash=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Edit: I've also tried changing the ipport value to the real internal IP of the server as well as the public IP but no change.
So, why can't I access SignalR from the same server?
I found a solution in another answer here that worked. I changed:
$j.connection.hub.start().done(function () {
To:
$j.connection.hub.start({ jsonp: true, xdomain: true }).done(function () {
Which worked for both internal and external clients. xdomain:true alone didn't work but when I added jsonp:true it did. I have no real idea why, just that it's working now.

Consume third party API with Blazor WebAssembly [duplicate]

I have a blazor web assembly which fetches from an external API built on ASP.NET Core which I do not have access to. I can perform get requests, but cannot perform post requests. I get the following error when I do.
Access to fetch at 'http://external:9000/User/Create' from origin 'http://localhost:56138' 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.
The author of the api confirms he enabled cors to allow any header in his startup and also suggested I do the same but this did not fix the issue. I confirmed from the debugger I am sending the right data format the endpoint requires and I am also running on http scheme same as the web service.
This is the client configuration in program.cs
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://external:9000/") });
builder.Services.AddCors(policy =>
{
policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
This is how I post
var dataJson = JsonConvert.SerializeObject(application);
var stringContent = new StringContent(dataJson, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"User/Create", stringContent);
I have read this is a common problem with blazor assembly, I'm not entirely sure of what I read. I am currently trying to move the project to blazor server to see if it would work, but I would prefer it on web assembly.
builder.Services.AddCors(policy =>
{
policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
This configuration should be done on a Server, and not yours but the server of the external API. You do nothing in that regard, except call end points on that Web Api.
The author of the api confirms they enabled cors to allow any header in his startup
If so, ask them for the code for confirmation...
and also suggested I do the same but this did not fix the issue.
You do nothing of the sort.
Workaround solution:
AS CORS is a security feature of JavaScript enforced by the browser, you can circumvent it by calling your Server code from which you perform the call to this Web Api end point, and then returns it back to your WebAssembly front-end. Use asynchronous code as much as you can.
Update as per comment
Are you saying I should have two projects, the server and the client under one solution? The server calls the calls the external api, then passes it to the client. Is this what your last suggestion is?
If you're using WebAssembly Blazor App hosted wherein the hosting server contains Web Api controllers, then you should expose end points that can be called from your WebAssembly front-end. The code in these end points should perform the HTTP calls to the external Web Api, and pass back to the WebAssembly calling methods the data received from the external Web Api.
Note: If you don't have such controllers ( they are created by default by Visual Studio), you may add them yourself to the server project.
If you already have created a Web Api project instead of those controllers, then expose the necessary end points from your Web Api project. Note that it makes no difference whether your Web Api project resides in the same solution of the WebAssembly front-end, as long as you provide the correct Url.
If you're using WebAssembly Blazor App stand alone; that is, the default installation does not create a Server project, you'll need to create a Web Api project and use it, unless you've already created one.
You are working with localhost so you should use this configuration to your Server:
builder.Services.AddCors(policy =>
{
policy.AddPolicy("_myAllowSpecificOrigins", builder =>
builder.WithOrigins("http://localhost:56138/")
.SetIsOriginAllowed((host) => true) // this for using localhost address
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
//
app.UseCors("_myAllowSpecificOrigins");

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.

Load balanced proxy server that change the request path for an ASP.NET Core 3.0 wep app

I have an asp.net core 3.0 application hosted behind a proxy server. The URL is rewritten when forwarded to the docker image that is running the application. I can't seem to get authentication to work as the redirect is computed to the wrong url. When i manually fix the redirect url, the authorization end point doesn't catch the call back. The documentation seems to indicate some combination of using UsePathBase and/or setting the Request.PathBase. I've tried this and still can't seem to get it correct. Here is my setup.
public url: http://app.com/foo/api/1
docker url: http://docker/
When the OAuth Authentication (Microsoft.AspNetCore.Authentication.OAuth) computes the redirect, it computes http://app.com/authorization-code/callback which is incorrect. I've tried manually setting the callback path to get around that issue. However, now the /authorization-code/callback endpoint is not hit when the authentication server redirects back to http://app.com/foo/api/1/authorization-code/callback
What are the correct settings in this situation?
thanks for the help
~ Paul

How can I implement ServiceStack.net rest call over HTTPS?

I would like to authenticate users of my servicestack.net rest services using basic auth over HTTPS.
Can anyone explain how the https portion of this would work or point me in the right direction? Is it the responsibility of the client to ensure the calls are made over https? Do I need to do anything involving SSL Certificates to enable this?
This service will most likely live on AppHarbor if that matters.
EDIT
Can anyone cite specific examples of how to accomplish this in service stack. I think that I would be having all of the services in my api require HTTPS. Would I be able to accomplish this using request filters?
You will need to have an SSL Certificate purchased and installed to handle https (you should be able to get one from your domain name provider, which you will then need to install on your hosting server). The service clients will generally be allowed to connect by any method they choose. It will be your responsibility to stop the request and generate an error message to the client if they attempt to connect by http, instead of allowing them access.
You can validate whether they are on http or https by checking the Request.Url.Scheme property in your REST Service API. Typically, a request for http on a service that requires https will return an HTTP 403 (forbidden) status code. If you have access to IIS, you can force HTTPS easily without doing any coding: http://www.sslshopper.com/iis7-redirect-http-to-https.html
If you don't need on all services the following at the top of any service that needs the security does the job:
if (!Request.IsSecureConnection)
{
throw new HttpError(HttpStatusCode.Forbidden,"403","HTTPS ONLY");
}
However it's better to this as a filter attribute: https://github.com/ServiceStack/ServiceStack/wiki/Filter-attributes
If you want it globally, you could apply your attribute to a shared BaseService or better use a global filter: https://github.com/ServiceStack/ServiceStack/wiki/Request-and-response-filters
...Like this:
this.GlobalRequestFilters.Add((req, res, dto) =>
{
if (!req.IsSecureConnection)
{
res.StatusCode = (int)HttpStatusCode.Forbidden;
res.Close();
}
});
If you want one that redirects to https rather than reject request then you could base it on this: http://weblogs.asp.net/dwahlin/requiring-ssl-for-asp-net-mvc-controllers

Categories