Swagger page being redirected from https to http - asp.net-web-api

AWS Elastic Load Balancer listening through HTTPS (443) using SSL and redirecting requests to EC2 instances through HTTP (80), with IIS hosting a .net webapi application, using swashbuckle to describe the API methods.
Home page of the API (https://example.com) has a link to Swagger documentation which can bee read as https://example.com/swagger/ui/index.html when you hove over on the link.
If I click on the link it redirects the request on the browser to http://example.com/swagger/ui/index.html which displays a Page Not Found error
but if I type directly in the browser URL https://example.com/swagger/ui/index.html then it loads Swagger page, but then, when expanding the methods an click on "Try it out", the Request URL starts with "http" again.
This configuration is only for Stage and Production environments. Lower environments don't use the load balancer and just use http.
Any ideas on how to stop https being redirected to http? And how make swagger to display Request URLs using https?
Thank you
EDIT:
I'm using a custom index.html file

Seems is a known issue for Swashbuckle. Quote:
"By default, the service root url is inferred from the request used to access the docs. However, there may be situations (e.g. proxy and load-balanced environments) where this does not resolve correctly. You can workaround this by providing your own code to determine the root URL."
What I did was provide the root url and/or scheme to use based on the environment
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
...
c.RootUrl(req => GetRootUrlFromAppConfig(req));
...
c.Schemes(GetEnvironmentScheme());
...
})
.EnableSwaggerUi(c =>
{
...
});
where
public static string[] GetEnvironmentScheme()
{
...
}
public static string GetRootUrlFromAppConfig(HttpRequestMessage request)
{
...
}

The way I would probably do it is having a main file, and generating during the build of your application a different swagger file based on the environnement parameters for schemes and hosts.
That way, you have to manage only one swagger file accross your environments, and you only have to manage a few extra environnement properties, host and schemes (if you don't already have them)
Since I don't know about swashbuckle, I cannot answer for sure at your first question (the redirect)

Related

OpenAPI Specification 3.0 shows different url in browser and Servers dropdown

We are using OpenApi Specification v1.4.8. We have load balancer urls and domain url. Domain url http://market.place.com/productsservice/swagger-ui.html and load balancer url is http://7649263.path.aws.com/productsservice/swagger-ui.html.
Due some ongoing network issue with the domain, we have shifted to use load balancer url for testing the application. When I access swagger ui using the above load balancer url, I see the domain URL in servers dropdown(haven't added it anywhere). Thus the url in browser address bar and in Servers dropdown is different.
Since Swagger uses the base url from 'Servers' dropdown to fabricate paths for testing, and my domain is not working, I am not able to fire request from Swagger UI. The request work fine via postman when the url in browser that is load balancer url is used.
Is there some configuration which can make the Servers dropdown URL and Browser url base path same ? What we are trying to do is, the Servers dropdown needs to take the url as in the address bar of browser.
Probably you have openapi 3 configuration java class.
You should
new OpenAPI().addServersItem(...)
Edit your method like this.
private String ip="109.162.230.178"; //your ip
private String port="8587"; //your port
// if you have context add this line
private String context="tws"; //your context
#Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.addServersItem(new Server().url("http://"+ip+":"+port+"/"+context))
...
}
now your UI Combobox is like this :
For example my server static ip is
109.162.230.178
and i have to use this Openapi 3 UI
from another computer outside of my local network in Internet.
I think of the one reason why you have this issue. You should check in code if io.swagger.v3.oas.models.servers.Server is being used in OpenAPI configuration-
OpenAPI oas = new OpenAPI();
......
......
String url = "/market.place.com/"
List<Server> servers = new ArrayList<Server>();
Server server = new Server();
server.setUrl(url);
servers.add(server);
oas.setServers(servers);
If you are relying on programmatic approach for openAPI configuration and you have something like above in your code then that may be the reason why you are seeing your domain URI. You can replace it with correct URI to make it work.

Laravel forcing Http for asssets

this is a little bit strange because most of the questions here wanted to force https.
While learning AWS elastic beanstalk. I am hosting a laravel site there. Everything is fine, except that none of my javascripts and css files are being loaded.
If have referenced them in the blade view as :
<script src="{{asset('assets/backend/plugins/jquery/jquery.min.js')}}"></script>
First thing I tried was looking into the file/folder permissions in the root of my project by SSHing into EC2 instance. Didn't work even when I set the permission to public folder to 777.
Later I found out that, the site's main page url was http while all the assets url were 'https'.
I dont want to get into the SSL certificates things just yet, if it is possible.
Is there anyway I can have my assets url be forced to Http only?
Please forgive my naiveity. Any help would be appreciated.
This usually happens if your site is for example behind an reverse proxy, As the URL helper facade, trusts on your local instance that is beyond the proxy, and might not use SSL. Which can be misleading/wrong.
Which is probaly the case on a EC2 instance... as the SSL termination is beyond load balancers/HA Proxies.
i usually add the following to my AppServiceProvider.php
public function boot()
{
if (Str::startsWith(config('app.url'), 'https')) {
\URL::forceScheme('https');
} else {
\URL::forceScheme('http');
}
}
Of course this needs to ensure you've set app.url / APP_URL, if you are not using that, you can just get rid of the if statement. But is a little less elegant, and disallows you to develop on non https

WebApi: Use different Route prefix for http reservation and WebApi routes

I have a Windows Service which exposes some APIs via WebAPI and OData using http.sys (to facilitate port sharing):
/api
/odata
/swagger
I also have reservation with http.sys for the prefix https://+:1234/.
Additionally, I have a web site (SPA) which uses this API and I'd like it to run on the same port. UP to now, this was no problem, because I had static file hosting in the service. For various reasons, I moved the static file hosting to its own service. and changed my http.sys reservation to this:
Static file hosting (Weak wildcard):
https://*:1234/
Service (strong wildcard):
https://+:1234/api/
https://+:1234/swagger/
https://+:1234/odata
And in my service I changed my
WebApp.Start("https://+:1234", Startup);
to
var options = new StartOptions
{
urls =
{
"https://+:1234/api/",
"https://+:1234/swagger/",
"https://+:1234/odata/",
}
};
_Service = WebApp.Start(options, Startup);
However, now the routes to the WebApi are https://+:1234/api/api/ and I can even use https://+:1234/api/odata/, which is kind of understandable, but not what I intended.
Can I trick WebApi that while it registers itself with http.sys on the three listening urls but always uses https://+:1234/ as the base for the routing?
This is nice question, I was tried different ways ..., But I had same experiences what you got right now....
Finally, I have understand, We can achieve your excepted out put with the UrlPrefixCollection Here is Url : https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.server.httpsys.urlprefixcollection?view=aspnetcore-2.2

How to enable CORS on Sonatype Nexus?

I want to develop a Monitoring-WebApp for different things with AngularJS as Frontend. One of the core-elements is showing an overview of Nexus-Artifacts/Repositories.
When I request the REST-API I'm getting following error back:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:9090' is therefore not allowed access.
To fix this error, I need to modify the response headers to enable CORS.
It would be great if anyone is familiar with that type of problem and could give me an answer!
The CORS headers are present in the response of the system you are trying to invoke. (Those are checked on the client side [aka browser this case], you can implement a call on your backend to have those calls and there you can ignore those headers, but that could become quite hard to maintain.) To change those you'll need a proxy. So your application will not call the url directly like
fetch("http://localhost:9090/api/sometest")
There are at least two ways: one to add a proxy directly before the sonar server and modify the headers for everyone. I do not really recommend this because of security reasons. :)
The other more maintaneable solution is to go through the local domain of the monitoring web app as follows:
fetch("/proxy/nexus/api/sometest")
To achieve this you need to setup a proxy where your application is running. This could map the different services which you depend on, and modify the headers if necessary.
I do not know which application http server are you going to use, but here are some proxy configuration documentations on the topic:
For Apache HTTPD mod_proxy you could use a configuration similar to this:
ProxyPass "/proxy/nexus/" "http://localhost:9090/"
ProxyPassReverse "/proxy/nexus/" "http://localhost:9090/"
It is maybe necessary to use the cookies as well so you may need to take a look at the following configurations:
ProxyPassReverseCookiePath
ProxyPassReverseCookieDomain
For Nginx location you could employ something as follows
location /proxy/nexus/ {
proxy_pass http://localhost:9090/;
}
For node.js see documentation: https://github.com/nodejitsu/node-http-proxy
module.exports = (req, res, next) => {
proxy.web(req, res, {
target: 'http://localhost:4003/',
buffer: streamify(req.rawBody)
}, next);
};

WebAPI SignalR Negotiate response different on different browsers

The main problem about Access-Control-Allow-Origin I think. But when I configure the Web API project as defined in the given documentation, it still not working in chrome and firefox but working in IE well (it is about IE thinks localhost is not cross domain, AFAIK). I tried different ways to make it work but no result.
I put the example project to github repository. Project is very simple. There are two applications working on cross domains. It is very simple chat application like in signalr examples.
You must change the value of api host in client javascript file:
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApp/Scripts/app/chat.js#L2
When you open the Chat page in mvc project, there will be two requests to api application
1- Regular ajax request (which is working fine)
2- Signalr negotiate request (cancelled)
And also I don't think browser disables the CORS because of if it disables there would not be an hit to server. So I think it is about browser but not about browser disables (something else).
Details are in repository
Readme: https://github.com/yusufuzun/WebApiSignalR/blob/master/README.md
Fiddler Results: https://github.com/yusufuzun/WebApiSignalR/blob/master/FiddlerResults
The bad part about it also is server returning 500 with this error:
System.InvalidOperationException: 'chat' Hub could not be resolved.
Which hub name is chat also.
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Hubs/ChatHub.cs#L10
You can enable CORS for Web Api in project with different ways for test purposes. Each one is giving different errors all about XMLHttpRequest Access-Control-Allow-Origin.
I commented them, so you can uncomment and make test for each one:
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Global.asax.cs#L24
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/App_Start/WebApiConfig.cs#L14
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/App_Start/WebApiConfig.cs#L16
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Controllers/ChatController.cs#L17
So what is going on here?
After I talked with David Fowler in JabbR, he mentioned the thing about using CORS with SignalR. My signalr startup code was wrong. So after changing the startup code like in his advice it worked well.
He also mentioned SignalR and Web API are working with different CORS definitions. So enabling or disabling one doesn't affect other.
Here is the new startup code:
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
});
});
The old one:
app.MapSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
}).UseCors(CorsOptions.AllowAll);
Hope it helps to somebody out there.

Resources