Im letzten Post habe ich mir OneLogin angeschaut und zwei Javascript Beispiele zum laufen gebracht.
In diesem Post möchte ich einen Reverse Proxy aufbauen, der eine öffentlich zugängliche Seite bereit stellt und eine private Seite nur für eingeloggte Mitglieder.
OneLogin
Auf der OneLogin Applications Seite sammle ich folgende Informationen ein, die später in der ReverseProxy Konfiguration benötigt werden:
- Client ID
- Client Secret
- Issuer URL
Außerdem wird der Token Endpoint auf Basic gesetzt.
![](https://ingo.kaulbach.de/wp-content/uploads/2022/05/image-1024x768.png)
In der Configuration muss eine Redirect URI eingetragen werden, in diesem Fall: http://localhost/private/redirect_uri
Reverse Proxy
Den Reverse Proxy wird mit Docker aufgebaut.
Der Reverse Proxy wird eine Startseite bereit stellen und von dort auf eine öffentlich zugängliche Unterseite und einen geschützten Bereich verlinken.
In der ersten Version wird der geschützte Bereich lediglich eine weitere Unterseite sein.
In der zweiten Version wird ein weiterer geschützter Bereich mit der ShowHeaders App hinzugefügt.
GitHub
Es wird ein Projekt auf GitHub für diesen Post angelegt: DockerOneLoginApacheSample
In Eclipse habe ich zuerst das neue GitHub-Repository hinzugefügt und ausgechecked, dann händisch .project angelegt und konnte dann in Eclipse über Import das Project hinzufügen.
Fühlt sich viel zu umständlich an, aber ich muss das zum Glück nicht so oft machen, als dass ich dem jetzt weiter auf dem Grund gehen müsste, wie das besser geht.
Apache Module OpenID
Für den Apache HTTP wird mod_auth_openidc verwendet.
Docker
Es wird ein Docker Image angelegt, das wiederum über Docker-Compose gestartet wird, um Dateien des Filesystems einzubinden. Das ist für die Entwicklung leichter, am Ende könnte man natürlich alles in ein Image packen und starten.
Das Docker Image basiert auf dem offiziellen Apache HTTPD Image.
Es wird mod_auth_openidc hinzugefügt, sowie ca-certificates um eine verschlüsselte Verbindung per HTTPS zum OneLogin-Server aufbauen zu können.
Die Datei für den mod_auth_openidc muss noch an die richtige Stelle verschoben werden und ein Backup der originalen httpd.conf angelegt werden.
FROM httpd:2.4 RUN apt update && apt install -y \ libapache2-mod-auth-openidc \ ca-certificates RUN cp /usr/lib/apache2/modules/mod_auth_openidc.so /usr/local/apache2/modules/ RUN mv conf/httpd.conf conf/container_httpd.conf CMD ["httpd-foreground"]
Im Docker-Compose wird das Image gebaut und die HTML Seiten sowie Konfigurationsdateien eingebunden.
version: '3.8' services: reverseproxy: build: ./reverseproxy hostname: reverseproxy volumes: - ./reverseproxy/public_html:/usr/local/apache2/htdocs - ${PWD}/reverseproxy/conf/reverseproxy_httpd.conf:/usr/local/apache2/conf/httpd.conf - ${PWD}/reverseproxy/conf/reverseproxy.conf:/usr/local/apache2/conf/reverseproxy.conf ports: - 80:80
Dabei wird die Datei reverseproxy_httpd.conf als httpd.conf eingebunden und über diese Datei wird die zuvor gesicherte, originale httpd.conf und anschließend die reverseproxy.conf geladen.
Das ist eine einfache Möglichkeit, die ursprüngliche Konfiguration zu erhalten. Für ein produktives Setup ist das vermutlich nicht die beste Wahl.
Die Variable ${PWD} ist unter Linux verfügbar, daher starte ich den Container unter Windows WSL.
Die Datei reverseproxy_httpd.conf (bzw. httpd.conf im Container) ist simpel aufgebaut und enthält nur die Includes zur ursprünglichen httpd.conf und zu unserer reverseproxy.conf:
# load original configuration first Include conf/container_httpd.conf # customized configuration ServerName reverseproxy Include conf/reverseproxy.conf
Apache HTTPD Konfiguration
Die in der OneLogin Seite eingesammelten Werte müssen entsprechend in die Konfiguration eingetragen werden.
Geschützt wird der Bereich, der unter /private liegt.
LoadModule proxy_module modules/mod_proxy.so LoadModule xml2enc_module modules/mod_xml2enc.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule auth_openidc_module modules/mod_auth_openidc.so <VirtualHost *:80> ServerAdmin deringo@github.com DocumentRoot "/usr/local/apache2/htdocs" ServerName localhost ## mod_auth_openidc ## https://github.com/zmartzone/mod_auth_openidc #this is required by mod_auth_openidc OIDCCryptoPassphrase a-random-secret-used-by-apache-oidc-and-balancer OIDCProviderMetadataURL https://deringo-dev.onelogin.com/oidc/2/.well-known/openid-configuration OIDCClientID geheim-a91c-013a-175a-02471d082b0b208817 OIDCClientSecret wirklich-ganz-geheim # OIDCRedirectURI is a vanity URL that must point to a path protected by this module but must NOT point to any content OIDCRedirectURI http://localhost/private/redirect_uri # maps the email/prefered_username claim to the REMOTE_USER environment variable OIDCRemoteUserClaim email #OIDCRemoteUserClaim preferred_username <Location /private> AuthType openid-connect Require valid-user </Location> </VirtualHost>
Befehle
Docker Container starten:
docker-compose up
In den laufenden Docker Container einloggen:
docker exec -it dockeroneloginapachesample_reverseproxy_1 bash
Im laufenden Docker Container den Apache neu durchstarten:
apachectl -t && apachectl restart
Testen
In einem neuen Browserfenster, im Inkognito Modus die Seite öffnen: http://localhost.
![](https://ingo.kaulbach.de/wp-content/uploads/2022/05/image-1.png)
Der Link Index Page führt auf diese Index-Seite, der Public Page Link auf die öffentlich zugängliche Seite und Private Page auf die Seite, die nur für OneLogin User zugänglich ist.
Die Public Page:
![](https://ingo.kaulbach.de/wp-content/uploads/2022/05/image-4.png)
Die Private Page führt im ersten Schritt zum OneLogin Login:
![](https://ingo.kaulbach.de/wp-content/uploads/2022/05/image-2.png)
Erst nach erfolgreichem Login sehen wir die private Seite:
![](https://ingo.kaulbach.de/wp-content/uploads/2022/05/image-5.png)
Reverse Proxy - mit ShowHeaders
Der Reverse Proxy schreibt einige Informationen in den Header, diese werden aber nur dem Server gesendet, der Client (zB unser Webbrowser) sieht davon nichts. Um sehen zu können, welche Informationen übermittelt werden, verwende ich eine kleine App, die nichts anderes macht, als die Header anzuzeigen, daher auch der Name ShowHeaders.
Bisher existierte noch kein Dockerfile für ShowHeaders, daher habe ich das für diesen Test entwickelt und hinzugefügt:
FROM tomcat:8.5-jdk8-openjdk-slim RUN apt update && apt install -y \ maven RUN git clone https://github.com/DerIngo/ShowHeaders.git WORKDIR ShowHeaders RUN mvn package WORKDIR $CATALINA_HOME RUN mv ShowHeaders/target/ROOT.war webapps EXPOSE 8080 CMD ["catalina.sh", "run"]
ShowHeaders wird in die Docker Konfiguration mit aufgenommen:
version: '3.8' services: reverseproxy: build: ./reverseproxy hostname: reverseproxy volumes: - ./reverseproxy/public_html:/usr/local/apache2/htdocs - ${PWD}/reverseproxy/conf/reverseproxy_httpd.conf:/usr/local/apache2/conf/httpd.conf - ${PWD}/reverseproxy/conf/reverseproxy.conf:/usr/local/apache2/conf/reverseproxy.conf ports: - 80:80 showheaders: build: ./showheaders hostname: showheaders ports: - 8080:8080
Die Reverse Proxy Konfiguration erweitern:
LoadModule proxy_module modules/mod_proxy.so LoadModule xml2enc_module modules/mod_xml2enc.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule auth_openidc_module modules/mod_auth_openidc.so <VirtualHost *:80> ServerAdmin deringo@github.com DocumentRoot "/usr/local/apache2/htdocs" ServerName localhost ## mod_auth_openidc ## https://github.com/zmartzone/mod_auth_openidc #this is required by mod_auth_openidc OIDCCryptoPassphrase a-random-secret-used-by-apache-oidc-and-balancer OIDCProviderMetadataURL https://deringo-dev.onelogin.com/oidc/2/.well-known/openid-configuration OIDCClientID geheim-a91c-013a-175a-02471d082b0b208817 OIDCClientSecret wirklich-ganz-geheim # OIDCRedirectURI is a vanity URL that must point to a path protected by this module but must NOT point to any content OIDCRedirectURI http://localhost/private/redirect_uri # maps the email/prefered_username claim to the REMOTE_USER environment variable OIDCRemoteUserClaim email #OIDCRemoteUserClaim preferred_username <Location /private> AuthType openid-connect Require valid-user </Location> # showheaders block ProxyPass /showheaders http://showheaders:8080/ ProxyPassReverse /showheaders http://showheaders:8080/ <Location /showheaders> AuthType openid-connect Require valid-user </Location> </VirtualHost>
Die Startseite wurde um einen Link zu ShowHeaders erweitert:
![](https://ingo.kaulbach.de/wp-content/uploads/2022/05/image-6.png)
Zuerst der OneLogin Login:
![](https://ingo.kaulbach.de/wp-content/uploads/2022/05/image-7.png)
Es werden alle übertragenen Header angezeigt:
Headers: host showheaders:8080 upgrade-insecure-requests 1 user-agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 accept text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 sec-fetch-site cross-site sec-fetch-mode navigate sec-fetch-user ?1 sec-fetch-dest document sec-ch-ua " Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101" sec-ch-ua-mobile ?0 sec-ch-ua-platform "Windows" accept-encoding gzip, deflate, br accept-language de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7 cookie mod_auth_openidc_session=13dc8a76-10b9-479f-94b1-53d7ddb760e2 oidc_claim_sub 175995661 oidc_claim_email Max@Mustermann.de oidc_claim_preferred_username Max@Mustermann.de oidc_claim_name Max Mustermann oidc_claim_nonce mXShr6JxWX49umdsGUDe2l1zmkB0eYs9Vx7Jm1We38Q oidc_claim_at_hash RBPJPDQuzxFJUembbLFdLg oidc_claim_sid 24f09d55-0a19-4a15-9446-010c84ff4461 oidc_claim_aud 22a153c0-a91c-013a-175a-02471d082b0b208817 oidc_claim_exp 1652179601 oidc_claim_iat 1652172401 oidc_claim_iss https://deringo-dev.onelogin.com/oidc/2 oidc_access_token eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVcIsIMtpZCI6IkpSY080bnhzNWpnYzhZZE43STJoTE80Vl9xbDFiZG9pTVhtY1lnSG00SHMifQ.eyJqdGkiOiJHWlJac0YyVVhrd0xrZEl3WGplNEoiLCJzdWIiOiIxNzU5OTU2NjEiLCJpc3MiOiJodHRwczovL2RlcmluZ28tZGV2Lm9uZWxvZ2luLmNvbS9vaWRjLzIiLCJpYXQiOjE2NTIxNzI0MDEsImV4cCI6MTY1MjE3NjAwMSwic2NvcGUiOiJvcGVuaWQiLCJhdWQiOiIyMmExNTNjMC1hOTFjLTAxM2EtMTc1YS0wMjQ3MWQwODJiMGIyMDg4MTcifQ.barxBngs7jirZS3nAsYMpsqBdwybrmuqzCtP1dTiwJxEkbQsRe77Z0xqdGRmXWG8sr6s65omAcyF8ZaacY51OMQiVmEriL9MUxBTG3Z4-noO9C0nq6wmMrwHBls5CG9BPhnoc-rWMB_fvsFELiP0WZk5FM4iV-POqUkJgCNTKLbyBjpkm4y6Q4IUBgCpqmuRCtgfq0jMDrXpxLkiKkya7UymtGref2pL6UurD5r0VLwvU75lV927SUyxCKnUIDOY7Mdv05BzBfrCg6KBibWunGuY9wh6xs9WWreBlu21JcZxdgYL8Vx_MPfXrTjfU-0sjhACaqn5h0nnCrwcLoK8Hw oidc_access_token_expires 1652176004 x-forwarded-for 172.24.0.1 x-forwarded-host localhost x-forwarded-server localhost connection Keep-Alive
Auffälligkeit
Die OIDCRemoteUserClaim-Konfiguration scheint keinen Einfluss zu haben:
# maps the email/prefered_username claim to the REMOTE_USER environment variable OIDCRemoteUserClaim email #OIDCRemoteUserClaim preferred_username
Auf der ShowHeaders-Seite werden oidc_claim_email und oidc_claim_preferred_username angezeigt. Hingegen wird keine Header REMOTE_USER angezeigt.
Das Entfernen der OIDCRemoteUserClaim-Konfiguration hat auch keinen Einfluss auf die angezeigten Header.
Anscheinend macht diese Konfiguration nicht das, was ich erwartet hatte, daher entferne ich sie wieder. Weitere Recherchen dazu sind für diesen Test nicht notwendig, daher belasse ich es dabei.
Weitere Informationen zur Konfiguration des Mod Auth OpenIDC finden sich in der kommentierten Beispielkonfiguration auf GitHub.
GitHub
Die Dateien zu diesem Post sind im OneLogin-GitHub-Projekt unter version1 und version2 zu finden.
Version1 ist ohne, Version2 ist mit ShowHeaders.
One reply on “Reverse Proxy mit OneLogin”
[…] die Benutzung der API wird Client ID und Client Secret benötigt. Das kennen wir schon aus einem vorherigen Post zu […]