Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
In my recent blog article: What's Changed - Setup Remote HANA Connection with SAML SSO in SAP BusinessObjects Cloud, I provided a sample Apache reverse proxy configuration based on an SAP NetWeaver SSO SAML 2 Identity Provider (IdP). The idea behind the configuration applies to most SAML 2 IdPs, but what about SAP Cloud Identity (SCI)? In this blog post, I'd like to walk you through some of the specifics we need to be aware of when configuring Apache reverse proxy for SCI.

Prerequisite: you need to be running Apache HTTPD server 2.4 or above.

Before I move further, a couple of housekeeping items to keep in mind:

1. This article assumes that the BusinessObjects Cloud (BOC) tenant has already been migrated to Simple URL. But the ideas of the tricks and workaround for SCI stay true even if the BOC tenant has not been migrated to Simple URL yet.

2. For SSO to HANA scenario, a dedicated SAML 2 IdP is required, i.e. the built-in common/shared SCI in BOC cannot be used in that case. However, the tricks in this artcile apply whenever a SAP Cloud Identity tenant is in use, no matter whether it is a shared SCI tenant or a dedicated SCI tenant.

Without further ado, let me explain what's so special with the SAP Cloud Identity SAML 2 Identity Provider. SCI is very strict about the HTTP request headers sent by the browser and any intermediate server in between, so we need to make sure that Apache reverse proxy does not send any unwanted HTTP headers as the reverse proxy. It has come to our notice that Apache sometimes seems to send unwanted HTTP request headers even when we just add a directive to manipulate HTTP response headers, such as changing cookie path, an essential step when we configure Apache reverse proxy for any SAML 2 IdP.

In order to workaround this Apache quirk, we need to do a few things:
1. Turn off (well, only partially) the behavior to add additional HTTP request headers by the following directive:
ProxyAddHeaders off
2. Make sure to change the IdP's cookie domain outside of a <Location> block.
3. Avoid changing IdP's cookie path with the directive ProxyPassReverseCookiePath. Instead, directly edit the Set-Cookie header with the "Header edit" directive. The following is an example:
Header edit Set-Cookie "^(.*; [Pp]ath=/)(.*)$" "$1sci/$2"

Here is a more complete example configuration for your reference:
#Load key modules for reverse proxy
LoadModule proxy_module modules/
LoadModule proxy_http_module modules/
LoadModule proxy_html_module modules/
LoadModule xml2enc_module modules/
LoadModule headers_module modules/

# Configure mod_proxy_html to understand HTML4/XHTML1
<IfModule proxy_html_module>
Include conf/extra/httpd-proxy-html.conf

Listen 443 https

<VirtualHost _default_:443>
SSLEngine on
SSLProxyEngine on
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLCertificateFile "${SRVROOT}/conf/ssl/reverseproxy.crt"
SSLCertificateKeyFile "${SRVROOT}/conf/ssl/reverseproxy.key"
DocumentRoot "${SRVROOT}/htdocs"
# DocumentRoot access handled globally in httpd.conf
CustomLog "${SRVROOT}/logs/ssl_request.log" \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
<Directory "${SRVROOT}/htdocs">
Options Indexes Includes FollowSymLinks
AllowOverride AuthConfig Limit FileInfo
Require all granted

#Proxy rules for the Central Redirect Node
ProxyPass /authn/ https://authn.<region>
ProxyPassReverse /authn/ https://authn.<region>
ProxyPassReverse /authn/ https://authn.<region>
<Location /authn/>
ProxyPassReverse /
ProxyHTMLEnable on
SetOutputFilter proxy-html
ProxyHTMLCharsetOut *
RequestHeader unset Accept-Encoding
ProxyHTMLURLMap https://<SAP_Cloud_Identity_Host>/ /sci/
ProxyHTMLURLMap https://<SAP_Cloud_Identity_Host>:443/ /sci/
ProxyHTMLURLMap https://customer.<region> /
ProxyPassReverseCookiePath / /authn/

#Proxy rules for remote on-premise HANA at https://righana2.yourcompany.corp:4300/
ProxyPass /righana2/ https://righana2.yourcompany.corp:4300/
ProxyPassReverse /righana2/ https://righana2.yourcompany.corp:4300/
<Location /righana2/>
ProxyPassReverse /
ProxyPassReverseCookiePath / /righana2
ProxyPassReverseCookiePath /sap/hana/xs/saml /righana2/sap/hana/xs/saml

#Proxy rules for the SAML 2 Identity Provider at https://<SAP_Cloud_Identity_Host>/
ProxyAddHeaders off
ProxyPass /sci/ https://<SAP_Cloud_Identity_Host>/
ProxyPassReverse /sci/ https://<SAP_Cloud_Identity_Host>/
ProxyPassReverse /sci/ https:/<SAP_Cloud_Identity_Host>:443/
ProxyPassReverseCookieDomain <SAP_Cloud_Identity_Host>
<Location /sci/>
Header edit Set-Cookie "^(.*; [Pp]ath=/)(.*)$" "$1sci/$2"
ProxyHTMLEnable on
SetOutputFilter proxy-html
ProxyHTMLCharsetOut *
RequestHeader unset Accept-Encoding
ProxyHTMLURLMap /ui/ /sci/ui/
ProxyHTMLURLMap /universalui/ /sci/universalui/
ProxyHTMLURLMap /saml2/ /sci/saml2/
ProxyHTMLURLMap https://authn.<region> /authn/
ProxyHTMLURLMap https://authn.<region> /authn/
ProxyHTMLURLMap https://righana2.yourcompany.corp:4300 /righana2

#Proxy rules for BOC (Simple URL) at https://customer.<region>
ProxyPass / https://customer.<region>
ProxyPassReverse / https://customer.<region>
ProxyPassReverse / https://customer.<region>
<LocationMatch "^/$|^/sap/fpa/ui/tenants/.*|^/logout.*">
ProxyHTMLEnable on
ProxyHTMLDocType "<!DOCTYPE html>" XML
SetOutputFilter proxy-html
ProxyHTMLCharsetOut *
RequestHeader unset Accept-Encoding
ProxyHTMLURLMap https://authn.<region> /authn/
ProxyHTMLURLMap https://authn.<region> /authn/


I hope this post will help you reduce the number of sleepless nights :).

Till next time. Stay tuned!