cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Setting up SSL/HTTPS - Hybris (TC) / Apache / Spring Security

Former Member
0 Likes
4,060

Is there a recommended approach or an example config for configuring SSL (with Apache as a proxy for Tomcat - port 80 and 443)?

We had a problem reaching HTTPS-pages , we'd get an infinite redirect loop when trying to reach the login/register page.

To 'solve' this, we have set all security-intercept rules in our storefront spring-security.xml to HTTP and let Apache take care of enforcing the SSL-encryption. As a consequence, some functionality in the storefront doesn't work anymore such as setting a GUID cookie etc., some methods check if the request is secure ( by calling request.isSecure() ). Since the require-channel is set to HTTP, hybris thinks the requests are insecure, but in reality they are secure. Removing these request.isSecure() checks does the trick, but this entire approach feels hacky and I'd like to do this the right way...

Thanks for your advice on this!

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Likes

The presence of a reverse proxy (or multiple proxies) is normally made transparent to the application (and especially to spring-security, so that you can keep it as it was during development) provided:

  • 1) the proper headers are added to the request by the reverse proxy, to keep track of the protocol (http, https) and the remote IP

  • 2) the headers are translated back into the HttpServletRequest by tomcat: the isSecure() flag, getRemoteAddr(), getServerPort() will transparently take the expected values

Fortunately:

  • apache, and other webServers/reverseProxies/gateways takes care of 1) automatically.

- To take care of 2), all you need is to use the RemoteIPValve in tomcat server.xml configuration:

 <Engine ...>
        <!-- Process X-Forwarded-For to get remote address and X-Forwarded-Proto to identify SSL requests. --> 
        <Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="x-forwarded-proto" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by"  />
        ...


Note that in above example, you can even add a internalProxies="${internalProxies.ipAddresses}" attribute and set the "internalProxies.ipAddresses" property in the local.properties file to list IP addresses of additional reverse proxies or gateways that would be in front of apache. This is optional, if browsers are making direct http(s) requests to apache, you can omit this attribute.

See RemoteIPValve Documentation for the list of all attributes of the tomcat valve.

Former Member
0 Likes

Thanks for this valuable information!

Server.xml is regenerated every time 'ant clean all' is called (during deployment). How can I persist this config setting?

Former Member
0 Likes

The server.xml to modify is in the hybris config dir. Ant script use this file as input for the plaform tomcat bundle.

Former Member
0 Likes

Got it, thanks!

Answers (3)

Answers (3)

Former Member
0 Likes

Your infinite loop is caused by tomcat unable to distinguish secure and unsecure request, so spring security redirect secure pages on inscure pages indefinitly. There is a lot of solution to this problem depending of your architecture, security constraint, etc.

The simple solution: use X-Forwarded-Proto header.

On your Apache part you should have 2 VirtualHost for HTTP and HTTPS (standard configuration on most distro).

HTTPS virtual host must set header X-Forwarded-Proto

 RequestHeader set X-Forwarded-Proto https


The 2 Apache VirtualHost could reverse proxy on the same port, 9001 for HTTP or better the AJP one 8009.

On your Tomcat server.xml you must have this valve so tomcat is able to mark request as secure:

 <Valve className="org.apache.catalina.valves.RemoteIpValve"
 remoteIpHeader="x-forwarded-for"
 remoteIpProxiesHeader="x-forwarded-by"
 protocolHeader="x-forwarded-proto"
 />

In hybris local.properties your website URL should also be configured to avoid some redirection problems:

 website.<site>.http=http://.../<storefront>
 website.<site>.https=https://.../<storefront>

Former Member
0 Likes

Thanks for the clarification!

Former Member
0 Likes

This has been covered many times on the Forum. Shame this site doesn't include any of that info. From three years ago.

How is your Apache marking the channel as secure? One assumes it will add a HTTP Header to requests, which is fairly standard. Then you need a ChannelProcessor to pick this up.

Former Member
0 Likes

BTW this is the correct approach. Using RemoteIPValve is a hack around this using something designed to solve a different problem.

Former Member
0 Likes

Can you perhaps explain how this would work? I should use a ChannelProcessor (in a beforeController interceptor I presume) to extract the X-Forwarded-Proto header, to see if 'https' is present, correct? Then, I somehow manually set the isSecure() field on the HttpServletRequest to true?

Former Member
0 Likes

Hi Vincent, There is no need to change the spring security config as long as you match the apache requests to the right port in hybris. e.g. https://apache:433 -> https://hybris:9002 and https://apache:80 -> https://hybris:9001

Here is an Nginx configuration we use:

 server {
     listen 443;
     server_name your.domain.com;
 
     location /
     {
 
         proxy_pass https://internal-hybris-server:9002;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
         add_header Front-End-Https on;
         proxy_set_header Host your.domain.com;
 
         proxy_redirect off;
     }
 }
 
 server {
     listen 80;
     server_name your.domain.com;
     
     location / {
 
 
         proxy_pass http://internal-hybris-server:9001;
 
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
 
         proxy_set_header Host your.domain.com;
         proxy_redirect off;
 
    }
 }
 

Former Member
0 Likes

Thanks for the example, Alex. If we want to serve the entire website with HTTPS, will it suffice to change the following spring-security.xml line to require the HTTPS channel

 <security:intercept-url pattern="/**" requires-channel="http" />

and set the Apache VirtualHost for port 80 to redirect (301) to https://hybris:9002?

Could you or someone else provide an Apache example perhaps? That would be very much appreciated! This will certainly help anyone looking up this topic 🙂

I have attached our current Apache config to redirect all HTTP traffic to HTTPS. Is this the correct approach?

https://justpaste.it/h8df

Former Member
0 Likes

Hello Alex,

In configuration you provided, won't ngnix forward requests to hybris via HTTPS because of proxy_pass https://internal-hybris-server:9002;?

If yes, it looks like there is double encryption client-ngnix-hybris. I might be wrong, just let me a note if it a case.

Thanks in advance, Ilya