Release a Spring (not boot) application running with HTTPS - spring

I try a SAML connection to Azure B2C with a Spring application found on GitHub.
Every works fine until I run in local, but when I need to test this application in a production eviroment I found myself up against problems due to HTTPS connection.
My production enviroment is based on AWS, I'm running a ECS Tasks configured in reverse proxy. I'm using an Load Balancer with an HTTPS listener and an HTTP rule to redirect on HTTPS.
This application is based on Spring, (not Spring Boot) and builds a WAR file that I run on a Tomcat 7.
When I try the login, this application try an HTTP request that the ALB redirect to HTTPS, but this redirect invalidate my SAML workflow.
I try to add requires-channel="https" to any <security:intercept-url /> node in my securityContext.xml but when I try to access to the application online I've got a ERR_TOO_MANY_REDIRECTS
I need to configure tomcat and this application to request only HTTPS without the needs of any redirects but I don't now how

I finnaly found a solution in two steps.
First step: I modify my Tomcat configuration to works only in https.
In server.xml I added a connector to works with TLS
<Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="conf/keystore.keystore"
keystoreType="JKS"
keystorePass="myStorePass"
keyPass="myPass" />
And then I removed redirect of 8080 to 443. Find the node Connector with protocol="HTTP/1.1" and remove it.
Second step: I modify Load Balancer to works only in HTTS with 443 port. To do this I had to create a new target group and a new service on my cluster.

Related

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

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.

Spring boot - Embeded Tomcat HTTP to HTTPS redirect

I'm using Java 7, Spring-Boot 1.1.7 and an ambeded Tomcat 7.
In the past, when I used a stand alone Tomcat, I used to add an http connector, that will redirect the requests to the HTTPS port :
<Connector port="8080" enableLookups="false"
redirectPort="8443" />
How can I do it when I'm using an embeded Tomcat (and I dont have a server.xml file) ?
You can add a Connector or configure the existing one with its Java API (e.g. see http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-enable-multiple-connectors-in-tomcat). The Connector has a setRedirectPort() (it's mapped directly by the XML <Connector/> element).

Is https necessary for client-cert authentication?

Spring Security: For testing an application I want to have SSL off the way
is https necessary for client-cert X.509 authentication?
Yes it is necessary. It is also extremely trivial to set it up. Please see:
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/x509.html
22.3 Setting up SSL in Tomcat
There are some pre-generated certificates in the samples/certificate directory in the Spring Security project. You can use these to enable SSL for testing if you don't want to generate your own. The file server.jks contains the server certificate, private key and the issuing certificate authority certificate. There are also some client certificate files for the users from the sample applications. You can install these in your browser to enable SSL client authentication.
To run tomcat with SSL support, drop the server.jks file into the tomcat conf directory and add the following connector to the server.xml file
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="${catalina.home}/conf/server.jks"
keystoreType="JKS" keystorePass="password"
truststoreFile="${catalina.home}/conf/server.jks"
truststoreType="JKS" truststorePass="password"
/>
clientAuth can also be set to want if you still want SSL connections to succeed even if the client doesn't provide a certificate. Clients which don't present a certificate won't be able to access any objects secured by Spring Security unless you use a non-X.509 authentication mechanism, such as form authentication.

redirection of https urls inside spring framework using spring security xml configuration

I have a Java EE setup with Apache in front end , jboss eap in backend. Have load balancer before apache layer.
I need to route all https requests hitting load balancer via apache to jboss. I use proxy pass for doing that in the apache connector layer. Have changed server.xml in jboss eap.
In login module we found that after logging in the page is getting redirected to url properly but :80 gets added to the IP address (https mode).
For example: When i click login url is https://1.1.1.1/tt/login.glx, after successful login it gets redirected to https://1.1.1.1:80/tt/view.glx
Not sure what is missing ?
Any ideas ?
We are using spring container and it does the redirection to another page using below setting in the context xml file.
<form-login login-page="/login.glx" default-target-url="/view.glx" always-use-default-target='false' authentication-failure-url="/failed.glx"/>

Login loop with Spring Security requires-channel and Amazon Elastic Load Balancer

I'm trying to get my spring security working on a server using Amazon Elastic Load Balancer (ELB). The ELB is configured on port 80 to forward to my app on port 8080 and on port 443 to also forward to 8080.
<security:intercept-url pattern="/login.xhtml" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https" />
<security:port-mappings>
<security:port-mapping http="80" https="443" />
</security:port-mappings>
Whenever I access this page I get into a login loop. Any idea how to solve this? Not sure if Spring Security is having issues with the fact ELB is forward traffic from https port 443 to my app on port 8080.
It turns out that Spring Security uses ServletRequest.getServerPort() to determine whether it is using a secure port. My tomcat was configured using 8080 and 8443 so when the ELB forward the request from 443 to my internal tomcat on 8443 the webapp did not accept this as a secure port:
20 Jun 18:16:49,184 ["http-bio-8443"-exec-5] DEBUG org.springframework.security. web.access.channel.RetryWithHttpsEntryPoint - Redirecting to: /login.xhtml
I also tried using the proxyport but couldnt get this to work.
Also if you configure the spring security ports to use 8443 instead then it doesnt do the redirect correctly (it will redirect the app to 8443 which doesnt exist externally).
Long story short...the following settings worked:
ELB forward 80->80 and 443->443.
Setup tomcat to use 80 and 443.
Setup port mappings to use 80 and 443 on Spring Security
A redirect loop almost always happens because you have a secured URL which should not be secured. All URLs are secured by default in spring security.
Also if JavaScript, CSS or image resources are loaded with separate requests by the login page their URLs are also secured and this might be causing the loop.
Enable the debug log and you should see why you get redirected.
This will help you on debug logging (search the page for debug).

Resources