Web app with multiple domains pointing to subfolders of a parent one - spring

I’m developing an application with Spring Boot, which runs under a domain, let’s say;
parentdomain.com
From one side the users enter their content, after logging in, at parentdomain.com/admin. This content is processed and made publicly accessible at a subfolder, let’s say;
parentdomain.com/user-one-content
parentdomain.com/user-two-content and so on.
I need to point a domain for each user to his folder, for example:
userone.com should be equivalent to parentdomain.com/user-one-content
The navigation should remain in the userone.com website.
userone.com/first-page should open parentdomain.com/user-one-content/first-page.
Right now the app is installed at PWS (Pivotal Web Services), but their routing system, doesn’t provide a solution to this approach, with multiple domains pointing to subfolders of a parent one.
How could I archive this functionality?

I would leave Spring Boot alone and put in a web server in front of it. Can you install Apache or Nginx? Domain/sub-domain rerouting is out of the box in both of them.

At the end I could archive it, thanks to the advice from gspatel
With the rooting system of PWS, or other IaaS cloud provider I can root each domain to the whole application.
Implementing the preHandle method of a HandleInterceptor, I check whether the request is coming from my domain (parentdomain.com in the example). Or if it is coming from a domain of the sites, that the app is serving (userone.com in the example). In that case, I control that doesn't access the parentdomain.com, or the content of other users, forwarding the request to the user home page (user-one-content in the example).
That's an extract, of my preHadle implementation:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
...
String URI = request.getRequestURI();
String rootURI = "/" + idweb + "/";
if(URI.equals("/") || !URI.startsWith(rootURI)){
URI = rootURI;
RequestDispatcher requestDispatcher = request.getRequestDispatcher(request.getContextPath() + URI);
requestDispatcher.forward(request, response);
}
return true;
}

Related

Redirection from Spring Boot Application of External Website

I am building a Spring Boot Application with SSL enabled.
Now when I am redirecting to some external website with leading http:// explicitly.
for example http://www.example.com. But browser is redirecting it to https://www.example.com
automatically.
As I am not sure the target site is http or https. I want to redirect to the target as it is in my database.
Is there any one could help regarding this issue?
I have tried by returning redirect:http://www.example.com and ModelAndView approach. It did not work.
Note: My action can return html view or redirect to external site.
Try This :
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public void method(HttpServletResponse httpServletResponse) {
httpServletResponse.setHeader("Location", projectUrl);
httpServletResponse.setStatus(302);
}
I tried by different ways from the Application. But it never worked.
DevOps have added Load Balancer in the middle and something messed up while setting the Load Balancer rules. They have modified at their end. Now it's working fine.

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.

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 forward to an external url?

My Spring based app is running under http://localhost. Another app is running under http://localhost:88. I need to achieve the following: when a user opens http://localhost/page, a content of http://localhost:88/content should be shown.
I've supposed, that I should use forwarding, like shown bellow:
#RequestMapping("/page")
public String handleUriPage() {
return "forward:http://localhost:88/content";
}
but seems like forwarding to an external URL doesn't work.
How can I achieve this behaviour with Spring?
Firstly, you specify that you want to show the content of "http://localhost:88/content" but you actually forward to "http://localhost:88" in your method.
Nevertheless, forward works with relative URLs only (served by other controllers of the same application), so you should use 'redirect:' instead.
Forward happens entirely on the server side: the Servlet container forwards the same request to the target URL, so the URL won't change in the address bar.
Redirect, on the other hand, will cause the server to respond with 302 and the Location header set to the new URL, after which the client browser will make a separate request to it, changing the URL in the address bar, of course.
UPDATE: For returning the content of the external page as it would be an internal one, I would write a separate controller method to make the request to the URL and just return its content. Something like the following:
#RequestMapping(value = "/external", produces = MediaType.TEXT_HTML_VALUE)
public void getExternalPage(#RequestParam("url") String url, HttpServletResponse response) throws IOException {
HttpClient client = HttpClients.createDefault();
HttpGet request = new HttpGet(url);
HttpResponse response1 = client.execute(request);
response.setContentType("text/html");
ByteStreams.copy(response1.getEntity().getContent(), response.getOutputStream());
}
Of course, you have many possible solutions. Here I used Apache Commons HttpClient for making the request, and Google's Guava for copying the response from that request to the resulting one.
After that, your return statement would change to the following:
return "forward:/external?url=http%3A%2F%2Flocalhost%3A88%2Fcontent"
Note how you need to encode your URL given as parameter.

Swagger page being redirected from https to http

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)

Resources