Spring Boot & ELB - How do I make the load balancer redirect http to https? - spring

I have deployed a Spring Boot application via Elastic Beanstalk. I'm using a load balancer, so this is the flow (as far as I understand):
Internet/Browser request ---HTTPS---> Load Balancer ---HTTP---> Spring Boot App Server
So essentially, the SSL terminates at the load balancer and the app server just deals with plain old HTTP.
But in the case of a HTTP request from the browser, I would like the load balancer to automatically redirect to HTTPS.
There are several questions about this issue:
Spring Boot with Embedded Tomcat behind AWS ELB - HTTPS redirect
How to redirect automatically to https with Spring Boot
Spring Boot redirect HTTP to HTTPS
But none of the answers to these questions make sense to me. Perhaps I'm misunderstanding, but all the answers basically make the Spring Boot app only server HTTPS request (for example when using http.requiresChannel().anyRequest().requiresSecure()).
However, this goes against the flow because I'm perfectly fine with the SSL terminating at the load balancer and the Spring Boot app server just dealing with HTTP. So if I require SSL at the spring boot level, then I'll need to do an end-to-end SSL connection, which isn't really required for my application.
I have also used the following properties, which don't seem to help either:
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto

With the help of this article, I was finally able to figure out how to do this for a Spring Boot app in an ELB environment.
I had to create a conf file in src/main/webapp/.ebextensions/nginx/conf.d. I just called it myconf.conf.
In myconf.conf, I put this code in:
server {
listen 80;
server_name www.my-site.com;
if ($http_x_forwarded_proto != "https") {
rewrite ^(.*)$ https://$server_name$REQUEST_URI permanent;
}
}
Also, make sure that both HTTP and HTTPS listeners are open for the load balancer.
Additionally, my spring boot app only opens up HTTP since the load balancer already terminates SSL.

AWS Load balancer cannot handle redirection. You may do it via your server or by using cloudfront distributions.

Related

How to configure spring boot for receive traffic only NGINX

For secure reasons I need my backend receive traffic only through Nginx. Is it possible to block outside all traffic to spring boot. And only NGINX can accept and send requests to Spring Boot application. Thanks for advice. Sorry for asking question in wrong so without code.

Spring boot API endpoint does not work after setting the DNS record

I have a spring boot web service running on localhost:8000 with an embedded Apache Tomcat.
Frontend is developed using Angular and is running on nginx and port 80. Connection between front- and back-end is established with a REST API endpoint, i.e. /v1/getdata/...
We have a static IP and outside access is OK with this configuration. But after setting a DNS record, i.e. https://x.y.com for the static IP, the spring web server does not return data and ERR_TUNNEL_CONNECTION_FAILED error is occurred in Angular, although the front-end is loaded successfully on port 80.
The only server-side configurations in Spring app is server.port=8000 and CORS configs.
I have set [STATIC-IP]:8000 and https://x.y.com:8000 for the api address in Angular but neither worked. However accessing with static IP is still working.
I think there is a problem with SSL configuration.
Any Ideas?

How to treat request from HTTP and HTTPS inseparately Spring Boot 2 to run Tomcat on two separate ports?

I am adding the secure port with the non-secure port already opened. I wants to separate the traffic between two and forward to different Spring boot 2 Controllers. Wonder how I can achieve that?
In most solutions I have seen so far, https / SSL is terminated infront of Tomcat or Spring Boot application, so that Tomcat / Spring Controller receives only http requests on port 8080 (for example).
Termination of SSL in front of Tomcat / Spring Boot could be done with a Reverse Proxy or Web Server, like Apache2 or nginx.
Then the communication flow looks like this:
User ==HTTP-80==> Apache2 ==HTTP-8080==> Tomcat/Spring Boot
User ==HTTPS-443==> Apache2 ==HTTP-8080==> Tomcat/Spring Boot
("HTTP-80" means HTTP protocol on port 80. "== ==>" is arrow showing communication flow.)

Spring Cloud Zuul + Undertow + OAuth2: Cannot log in to Zuul

We are using Spring Boot v2.0.4 + Spring Cloud (Finchley release).
We have deployed Zuul, Auth Server, Eureka, and Config Server, each in their own separate applications / processes. We have half a dozen of our own services deployed. We are using OAuth2 authentication for all services. We are using the embedded undertow container for all apps.
When Zuul uses the embedded Undertow container, we can not log in- the login page is redisplayed even though the credentials are correct. When Zuul is switched to use the embedded Tomcat container, everything works correctly- logging in brings the user to the correct page. (All other apps use Undertow in both cases.)
When we debug the requests coming through Zuul for Tomcat vs Undertow, we see that the SPRING_SECURITY_CONTEXT session attribute is being set for Tomcat but is not being set for Undertow. I assume this means that the user will be redirected back to the login page, which is why we are seeing that behavior.
We know that it is an issue with Zuul + Tomcat vs. Undertow, since the configuration of all other apps remains exactly the same.
Any ideas? We are really scratching our heads over this one.
It turned out this was caused by JSESSIONID cookie name conflict between Zuul and Auth Server. Because Tomcat container has different handling than Wildfly for multiple Set-Cookies of the same name (which is in violation of RFC6265), we are only seeing it now.
I should have mentioned that we configured auth server to be behind the Zuul proxy, hence the multiple JSESSIONID cookies.
We fixed this for now by renaming the JSESSIONID cookie name on all back-end servers. We will investigate the best way to do this for production deployment going forward, perhaps by using Spring Session. Any suggestions welcome.

How to drop HTTP request on non-existing URL with Spring Boot?

I deployed a webserver on AWS Beanstalk. The log file shows there are quite some HTTP requests to URLs that do not exist on my webserver. Those requests cause Spring Boot to forward the requests to /error, for which I have a controller to process.
Those URLs are
/hedwig.cgi
/system.ini
/upgrade_handle.php
/board.cgi
/shell
/azenv.php
Does it mean someone is trying to attack my website? How can I configure Spring Boot or Beanstalk to match those URLs and drop the request so that they do not reach to my controller handling /error?

Resources