SSD Nodes Learn 🎉 VPS vanaf $5.50/mnd
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-08-21

Applicatie beveiligen met SSO via oauth2-proxy

Beveilig applicaties zonder eigen inlogscherm met oauth2-proxy via forward auth. Voorkom cookie- en redirectfouten door de juiste configuratie in Nginx of Traefik toe te passen.

Forward auth: hoe een applicatie zonder inlogscherm SSO krijgt

oauth2-proxy biedt single sign-on voor een applicatie die zelf geen inlogfunctionaliteit heeft. Dit werkt doordat de reverse proxy die voor de applicatie staat, elk verzoek onderschept, aan oauth2-proxy vraagt of het verzoek een geldige sessie bevat, en het verzoek alleen doorstuurt naar de upstream als het antwoord bevestigend is. De applicatiecode hoeft niet te worden aangepast, omdat de applicatie de controle zelf nooit ziet.

De controle bestaat uit één extra HTTP-verzoek. De proxy stuurt een kopie van de inkomende request headers naar /oauth2/auth en leest de statuscode uit. Een 202 betekent dat de aanroeper een sessie heeft, dus stuurt de proxy het oorspronkelijke verzoek door naar de app. Een 401 betekent dat er geen sessie is, dus stuurt de proxy de browser naar /oauth2/sign_in, wat een OpenID Connect (OIDC) login start bij uw identity provider. OIDC is de identiteitslaag die boven op OAuth 2.0 is gebouwd, en de provider is de dienst die u al gebruikt voor inlogprocedures.

Dit patroon heeft in elke reverse proxy een eigen naam. Nginx noemt de directive auth_request. Traefik noemt de middleware forwardAuth. Caddy noemt het forward_auth. De service die het sub-verzoek beantwoordt is eveneens uitwisselbaar. oauth2-proxy is de meest gekozen optie omdat deze standaard OIDC spreekt en geen eigen database vereist.

Bepaal de vertrouwensgrens voordat u configuraties schrijft

Na een geslaagde controle stuurt oauth2-proxy de identiteit terug als response headers, waarna de reverse proxy deze kopieert naar de upstream-aanvraag. Met set_xauthrequest ingeschakeld krijgt u X-Auth-Request-User en X-Auth-Request-Email. De applicatie leest deze headers en vertrouwt ze.

Dit is het volledige beveiligingsmodel, dus spreek de consequentie hardop uit. Alles wat een TCP-verbinding kan openen naar de applicatiepoort, kan deze headers zelf instellen en zich voordoen als elke gebruiker. Een enkele curl -H "X-Auth-Request-Email: admin@example.com" http://app-host:3000/ is een volledige omzeiling als deze de applicatie rechtstreeks bereikt.

De applicatie mag daarom niet bereikbaar zijn, behalve via de proxy. Verwijder in Docker Compose de ports:-mapping van de applicatieservice en laat deze op het interne netwerk staan, zodat alleen de proxy-container verbinding kan maken. Bind de applicatie op een bare host aan 127.0.0.1:3000 in plaats van 0.0.0.0:3000. Controleer vervolgens wat u daadwerkelijk heeft blootgesteld:

sudo ss -tlnp | grep 3000

Een regel met 0.0.0.0:3000 betekent dat de applicatie antwoordt op het publieke IP-adres en dat uw beveiliging slechts decoratie is. 127.0.0.1:3000 is wat u wilt zien. Een firewallregel is een nuttige tweede laag, maar het bind-adres is de instelling die blijft bestaan als een andere tool uw regelset wist.

Installatie van oauth2-proxy

Sinds augustus 2026 is de huidige release v7.15.3, gepubliceerd in juni 2026. Installeer het binaire bestand en verifieer de download:

cd /tmp
curl -fsSLO https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.15.3/oauth2-proxy-v7.15.3.linux-amd64.tar.gz
curl -fsSLO https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.15.3/oauth2-proxy-v7.15.3.linux-amd64.tar.gz-sha256sum.txt
sha256sum -c oauth2-proxy-v7.15.3.linux-amd64.tar.gz-sha256sum.txt
tar -xzf oauth2-proxy-v7.15.3.linux-amd64.tar.gz
sudo install -m 755 oauth2-proxy-v7.15.3.linux-amd64/oauth2-proxy /usr/local/bin/oauth2-proxy
oauth2-proxy --version

sha256sum -c moet een regel afdrukken die eindigt op OK. Als het FAILED afdrukt, stop dan en download het bestand opnieuw in plaats van het binaire bestand uit te voeren.

In Docker is de image quay.io/oauth2-proxy/oauth2-proxy en u dient de tag vast te zetten: quay.io/oauth2-proxy/oauth2-proxy:v7.15.3. Het op latest laten staan verandert een routine-docker compose pull in een ongeplande upgrade van het proces dat elke applicatie op de server beveiligt.

Het sessie-cookie is versleuteld en cookie_secret fungeert als de sleutel. Deze moet exact 16, 24 of 32 bytes lang zijn, omdat deze wordt gebruikt als AES (Advanced Encryption Standard) sleutel. Bij elke andere lengte weigert oauth2-proxy te starten en verschijnt er een opstartfout die verwijst naar het cookie-secret.

openssl rand -base64 32 | tr -- '+/' '-_'

De tr is niet louter cosmetisch. Deze zet standaard base64 om naar een URL-veilig alfabet, waardoor de waarde correct wordt verwerkt in een shell, een env-bestand en een HTTP-header zonder problemen met aanhalingstekens.

Er gelden twee regels voor deze waarde. Gebruik een uniek secret voor elke implementatie. Wanneer u meer dan één oauth2-proxy instantie achter hetzelfde domein draait, moeten deze allemaal hetzelfde secret gebruiken, omdat een cookie dat door de ene instantie is versleuteld, leesbaar moet zijn voor de andere instanties.

De oauth2-proxy configuratie schrijven

Bewaar de instellingen in een bestand in plaats van een lange opdrachtregel, zodat het client secret nooit zichtbaar is in de ps output.

# /etc/oauth2-proxy/oauth2-proxy.cfg
http_address = "127.0.0.1:4180"
reverse_proxy = true

provider = "oidc"
oidc_issuer_url = "https://id.example.com/application/o/myapp/"
client_id = "REPLACE_ME"
client_secret = "REPLACE_ME"

redirect_url = "https://app.example.com/oauth2/callback"
cookie_secret = "REPLACE_ME"
cookie_secure = true
cookie_domains = [".example.com"]
whitelist_domains = [".example.com"]

email_domains = ["*"]
set_xauthrequest = true
upstreams = ["static://202"]

reverse_proxy = true instrueert oauth2-proxy om de X-Forwarded-* headers van de proxy ervoor te vertrouwen. Zonder deze instelling beschouwt oauth2-proxy het adres van de proxy zelf als het clientadres, waardoor de inschatting of het verzoek via HTTPS is binnengekomen onjuist kan zijn.

upstreams = ["static://202"] zorgt ervoor dat oauth2-proxy met 202 antwoordt op een geauthenticeerd verzoek zonder zelf verkeer door te sturen. Dit is precies wat forward auth vereist, aangezien de reverse proxy het doorsturen afhandelt. De andere implementatievorm plaatst oauth2-proxy direct in het verzoekpad met upstreams = ["http://127.0.0.1:3000"] en zonder enige auth_request. Dat is eenvoudiger voor één applicatie, maar schaalt niet naar tien.

email_domains = ["*"] accepteert elk adres dat uw provider authenticeert. Beperk dit tot uw eigen domein, of beter nog, beperk de toegang met een group binding in de provider, aangezien u daar al het gebruikersbeheer uitvoert.

Draai het onder systemd als een eigen gebruiker:

# /etc/systemd/system/oauth2-proxy.service
[Unit]
Description=oauth2-proxy
After=network-online.target
Wants=network-online.target

[Service]
User=oauth2-proxy
Group=oauth2-proxy
ExecStart=/usr/local/bin/oauth2-proxy --config=/etc/oauth2-proxy/oauth2-proxy.cfg
Restart=on-failure
ProtectSystem=strict
PrivateTmp=true
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
sudo useradd --system --no-create-home --shell /usr/sbin/nologin oauth2-proxy
sudo install -d -m 750 /etc/oauth2-proxy
sudo chown -R oauth2-proxy:oauth2-proxy /etc/oauth2-proxy
sudo chmod 600 /etc/oauth2-proxy/oauth2-proxy.cfg
sudo systemctl daemon-reload
sudo systemctl enable --now oauth2-proxy
curl -s http://127.0.0.1:4180/ping

/ping met de output OK betekent dat het proces is gestart en de configuratie heeft geladen. Dit is het eigen health-endpoint van oauth2-proxy en dit vereist nooit een sessie. Als er geen antwoord komt, lees dan journalctl -u oauth2-proxy -n 50, aangezien een onjuiste issuer URL en een cookie secret met de verkeerde lengte beide bij het opstarten falen en beide dit melden.

Registreer de redirect URI bij uw provider

Maak een OIDC-applicatie aan in uw provider en stel de redirect URI exact in op de redirect_url uit de configuratie: https://app.example.com/oauth2/callback. Exact betekent dat het schema, de host, de poort en het pad teken voor teken overeenkomen. Een afsluitende slash maakt het een andere URI.

Dit is het meest voorkomende probleem in de gehele installatie, en het treedt op nog voordat oauth2-proxy erbij betrokken is. De provider wijst het autorisatieverzoek af en toont zijn eigen foutpagina, waardoor er niets in het logboek van oauth2-proxy verschijnt. Het kenmerk is de adresbalk: de browser bevindt zich nog steeds op het domein van uw provider en de query-string bevat direct error=invalid_request of de paginanamen redirect_uri. Wanneer u dit ziet, corrigeer dan het applicatierecord bij de provider, niet in de configuratie van de proxy.

Kopieer de issuer URL van de provider in plaats van deze over te typen. oauth2-proxy voegt /.well-known/openid-configuration toe aan oidc_issuer_url en haalt dat discovery-document op bij het opstarten. Controleer dit eerst zelf:

curl -s https://id.example.com/application/o/myapp/.well-known/openid-configuration | head -c 400

JSON die een authorization_endpoint-sleutel bevat, betekent dat de issuer URL correct is. Een 404 of een HTML-foutpagina betekent dat deze onjuist is, en oauth2-proxy zal bij het opstarten op diezelfde 404 falen. Als u nog geen provider heeft gekozen, behandelt de vergelijking van Keycloak, Authentik en Zitadel de afwegingen, en het draaien van Authentik als uw eigen SSO-server doorloopt de provider-helft van deze exacte configuratie.

Nginx: auth_request

Nginx voert forward auth uit met auth_request, wat een intern sub-request activeert en vertakt op basis van de statuscode daarvan.

# in the http context, next to your other maps
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

server {
  listen 443 ssl;
  server_name app.example.com;

  location /oauth2/ {
    proxy_pass       http://127.0.0.1:4180;
    proxy_set_header Host                    $host;
    proxy_set_header X-Real-IP               $remote_addr;
    proxy_set_header X-Auth-Request-Redirect $request_uri;
  }

  location = /oauth2/auth {
    proxy_pass       http://127.0.0.1:4180;
    proxy_set_header Host             $host;
    proxy_set_header X-Real-IP        $remote_addr;
    proxy_set_header X-Forwarded-Uri  $request_uri;
    proxy_set_header Content-Length   "";
    proxy_pass_request_body           off;
  }

  location / {
    auth_request /oauth2/auth;
    error_page 401 = @oauth2_signin;

    auth_request_set $user  $upstream_http_x_auth_request_user;
    auth_request_set $email $upstream_http_x_auth_request_email;
    proxy_set_header X-User  $user;
    proxy_set_header X-Email $email;

    auth_request_set $auth_cookie $upstream_http_set_cookie;
    add_header Set-Cookie $auth_cookie;

    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host       $host;
    proxy_set_header Upgrade    $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
  }

  location @oauth2_signin {
    return 302 /oauth2/sign_in?rd=$scheme://$host$request_uri;
  }
}

Drie details hierin zijn essentieel. proxy_pass_request_body off met een lege Content-Length voorkomt dat nginx de body van elke POST kopieert naar het sub-request; dit is belangrijk omdat oauth2-proxy deze data niet leest. Bij het uploaden van een bestand zou de standaardinstelling het bestand anders twee keer versturen.

Het paar auth_request_set $auth_cookie en add_header Set-Cookie geeft een vernieuwde sessie-cookie door aan de browser. Laat u dit weg, dan doet cookie_refresh stilzwijgend niets, omdat nginx de Set-Cookie van het sub-request negeert en de browser de oude waarde behoudt totdat de sessie verloopt.

error_page 401 = @oauth2_signin zorgt ervoor dat een mislukte controle leidt naar een inlogpagina. Zonder deze instelling krijgt een niet-geauthenticeerde bezoeker een kale 401 Authorization Required-pagina te zien zonder mogelijkheid om verder te gaan.

Test altijd voordat u de configuratie opnieuw laadt:

sudo nginx -t && sudo systemctl reload nginx

Als de omliggende richtlijnen nieuw voor u zijn, behandelt de anatomie van een nginx reverse proxy configuratie de onderliggende laag.

Traefik: forwardAuth middleware

Traefik heeft twee middlewares nodig voor dezelfde taak. De eerste voert de controle uit. De tweede zet de 401-status om in een browser-redirect.

# dynamic configuration
http:
  middlewares:
    oauth-auth:
      forwardAuth:
        address: https://oauth.example.com/oauth2/auth
        trustForwardHeader: true
    oauth-errors:
      errors:
        status:
          - "401-403"
        service: oauth-backend
        query: "/oauth2/sign_in?rd={url}"
        statusRewrites:
          "401": 302

Koppel beide aan de router die voor uw applicatie staat en publiceer oauth2-proxy op een eigen router op oauth.example.com, omdat de browser /oauth2/sign_in en /oauth2/callback moet kunnen bereiken zonder de controle te passeren.

statusRewrites Het toewijzen van 401 naar 302 is het onderdeel dat vaak wordt vergeten. Zonder deze stap retourneert Traefik de inlog-redirect met een 401-status, volgt de browser deze niet en ziet de bezoeker een pagina met enkel het woord Found..

trustForwardHeader: true geeft de oorspronkelijke host en URI door aan oauth2-proxy, die deze nodig heeft om de rd-waarde op te bouwen waarmee de gebruiker terugkeert naar de opgevraagde pagina. Stel whitelist_domains zo in dat deze ook die host dekt, anders verwerpt oauth2-proxy de rd-parameter als een open-redirect-risico en belandt iedereen na het inloggen op /. Een Traefik-server staat doorgaans voor meerdere applicaties tegelijk, en meerdere Docker Compose-applicaties routeren via één Traefik-instantie toont de router-indeling waar dit op aansluit.

Caddy: forward_auth

app.example.com {
  handle /oauth2/* {
    reverse_proxy oauth2-proxy.internal:4180 {
      header_up X-Real-IP {remote_host}
      header_up X-Forwarded-Uri {uri}
    }
  }
  handle {
    forward_auth oauth2-proxy.internal:4180 {
      uri /oauth2/auth
      header_up X-Real-IP {remote_host}
      copy_headers X-Auth-Request-User X-Auth-Request-Email
      @error status 401
      handle_response @error {
        redir * /oauth2/sign_in?rd={scheme}://{host}{uri}
      }
    }
    reverse_proxy upstream.internal:3000
  }
}

De volgorde is hier van belang. Het /oauth2/*-blok komt eerst en bevat geen forward_auth, omdat een bezoeker die niet is ingelogd de paden voor aanmelden en de callback moet kunnen bereiken. Plaats de controle vóór deze paden, anders blijft de inlogpagina zichzelf omleiden totdat de browser de verbinding staakt.

copy_headers zorgt ervoor dat de identiteit wordt doorgegeven aan het upstream-verzoek; dit genereert alleen waarden wanneer oauth2-proxy draait met set_xauthrequest = true. De keuze tussen de verschillende proxies is een vraag op zich, en de vergelijking tussen nginx, Caddy en Traefik behandelt dit onderwerp uitgebreid.

Waarom keert de login terug naar de inlogpagina?

U meldt zich aan bij de provider, deze stuurt u terug, en oauth2-proxy stuurt u direct weer door naar de provider. De lus betekent dat het callback-verzoek is binnengekomen zonder de cookie die oauth2-proxy bij het vertrek had geplaatst. Het logboek benoemt de situatie:

No cookies were found in OAuth callback.

of, wanneer een andere cookie wel is aangekomen maar de juiste niet:

Cookies were found in OAuth callback, but none was a CSRF cookie.

CSRF staat voor cross-site request forgery; deze cookie bestaat zodat een callback gekoppeld kan worden aan de login die deze heeft gestart. De browser ziet dezelfde fout als:

Login Failed: Unable to find a valid CSRF token. Please try again.

Controleer deze vier oorzaken in volgorde.

  1. cookie_secure = true terwijl de browser de site via onversleuteld HTTP heeft bereikt. Een browser slaat geen cookie op die gemarkeerd is als Secure op een http://-oorsprong, waardoor deze nooit wordt teruggestuurd. Beëindig TLS (transport layer security) correct, of stel cookie_secure = false alleen in tijdens het testen op localhost.
  2. Een cookie_domains-waarde die de hostnaam in de adresbalk niet dekt. .example.com dekt app.example.com en doet niets voor app.example.net.
  3. De browser verwijdert de cookie. Een strikte privacy-extensie of het blokkeren van third-party cookies kan _oauth2_proxy_csrf verwijderen tussen de uitgaande redirect en de callback.
  4. Klokafwijking. Als de klok van de server ver afwijkt van die van de provider, vallen de iat en exp van het ID-token buiten het geaccepteerde venster en wordt de sessie bij aankomst geweigerd. timedatectl zou System clock synchronized: yes moeten rapporteren.

Observeer het proces vanaf de serverkant in plaats van te gissen:

sudo journalctl -u oauth2-proxy -f

Laad de app in een privévenster. Elk verzoek wordt gelogd met de bijbehorende status, dus een callback die direct wordt gevolgd door een nieuwe redirect naar de provider is de lus, zoals vastgelegd in het logboek.

Paden die de login moeten overslaan: API's, webhooks en websockets

Forward auth gaat uit van een browser die een cookie vasthoudt. Aanroepers zonder browser falen.

Een API-client die Authorization: Bearer <token> verstuurt, heeft geen cookie. Deze ontvangt een 302-redirect naar de inlogpagina van uw provider en probeert vervolgens HTML als JSON te parsen. Er zijn twee nette oplossingen. Door skip_jwt_bearer_tokens = true in te stellen, accepteert oauth2-proxy een geldig JWT (JSON web token) bearer-token van dezelfde uitgever; dit is de juiste keuze als uw API-clients al tokens van de provider ontvangen. Vrijgesteld het pad anders:

skip_auth_routes = [
  "^/api/",
  "POST=^/webhook/",
  "GET=^/healthz$"
]

Elke waarde is een reguliere expressie die wordt vergeleken met het genormaliseerde pad, optioneel voorafgegaan door een HTTP-methode en =. POST=^/webhook/ laat de webhook-ontvanger open voor POST, terwijl een menselijke gebruiker die naar hetzelfde pad navigeert, nog steeds de inlogpagina krijgt. Elk item is een gat in uw beveiliging, dus veranker de expressies met ^ en houd ze zo specifiek als de aanroeper toelaat.

Websockets zijn het geval waar mensen vaak de fout in gaan. Het upgrade-verzoek is een gewoon HTTP GET-verzoek dat dezelfde cookies draagt als elk ander verzoek; het passeert de controle dus normaal en heeft geen vrijstelling nodig. Wat wel breekt, is de proxying eromheen. Zonder de Upgrade en Connection headers op de beveiligde locatie wordt de upgrade nooit voltooid en blijft de client van de applicatie oneindig opnieuw proberen met een WebSocket connection ... failed-melding in de browserconsole. Het vrijstellen van het pad lost daar niets op, omdat het verzoek al geautoriseerd was.

Er is echter één reële beperking. De controle wordt eenmalig uitgevoerd, bij de upgrade. Een websocket die urenlang open blijft, wordt niet opnieuw gecontroleerd. Het verwijderen van een gebruiker in uw provider sluit de socket die zij al bezitten dus niet. Herstart de applicatie om actieve verbindingen te verbreken.

Standaard bevindt de volledige sessie zich in de cookie, versleuteld met uw cookie_secret. Hierdoor blijft oauth2-proxy stateless en is er geen extra service nodig. Er is echter een limiet, omdat browsers een cookie beperken tot ongeveer 4 KB. Wanneer het ID-token een lange lijst met groepsclaims bevat, splitst oauth2-proxy de sessie over _oauth2_proxy_0, _oauth2_proxy_1 en verder. Na enkele delen worden de request headers zo groot dat nginx antwoordt met 400 Request Header Or Cookie Too Large voordat de applicatie het verzoek ooit ziet.

Verplaats de sessie naar de serverzijde wanneer dit gebeurt:

session_store_type = "redis"
redis_connection_url = "redis://127.0.0.1:6379"

De browser bevat dan een kort ticket en de versleutelde sessie staat in Redis. De keerzijde is een service die altijd actief moet blijven: als Redis uitvalt, wordt elke sessie ongeldig en wordt iedereen tegelijkertijd uitgelogd. De cookie-opslag heeft zijn eigen nadeel: twee verzoeken die op hetzelfde moment dezelfde sessie verversen, kunnen conflicteren en een nieuwe login afdwingen.

Wat forward auth u niet biedt

Dit is een poortwachter bij de ingang. Het is geen autorisatie binnen de applicatie zelf, en dat verschil bepaalt of deze aanpak geschikt is voor uw situatie.

Zodra een gebruiker is toegelaten, ziet de applicatie wat deze altijd al zag. Als de applicatie eigen rollen heeft, vult forward auth deze niet in, tenzij de applicatie header-gebaseerde authenticatie ondersteunt en een header aan een account koppelt. Grafana doet dit via de auth.proxy-instellingen. De meeste zelfgehoste applicaties doen dit niet, waardoor iedereen die door de poort komt voor de applicatie dezelfde identiteit heeft, en die identiteit is vaak een beheerder.

Het beschermt ook niet de eigen API-tokens van de applicatie. Een persoonlijk toegangstoken dat door de app is uitgegeven, authenticeert bij de app, niet bij oauth2-proxy. Het token werkt dus niet meer zodra de poortwachter ervoor staat. Sluit het API-pad uit om dit te herstellen, maar dat token wordt dan de enige beveiliging voor dat pad. U draait nu twee authenticatiesystemen op één service, en SSO dekt er slechts één van.

Intrekking is het derde hiaat. Het verwijderen van een gebruiker bij uw provider stopt nieuwe aanmeldingen en stopt de tokenvernieuwing die cookie_refresh uitvoert, maar een bestaande sessie-cookie blijft geldig totdat deze verloopt. cookie_expire staat standaard op 168 uur, wat een week toegang betekent voor iemand die u zojuist heeft verwijderd. Stel cookie_refresh in op een korte duur, zoals een uur, zodat intrekking binnen dat tijdsbestek plaatsvindt.

Het audit-spoor stopt ook bij de poort. oauth2-proxy logt wie erdoor kwam en wanneer. De applicatie logt een naamloze sessie. Als u moet kunnen aantonen wie een instelling heeft gewijzigd, is header-identiteit in de app het minimum, en zijn echte per-gebruiker accounts het enige sluitende antwoord.

Wanneer het betalen van de SSO-toeslag de betere keuze is

Forward auth is het juiste instrument wanneer een applicatie geen inlogfunctie heeft, of gebruikmaakt van één gedeeld wachtwoord, en u op één centrale plek gebruikers wilt toevoegen en verwijderen. Het kost een middag werk en één extra proces, en het werkt met elke applicatie die HTTP ondersteunt.

Het is het verkeerde instrument wanneer verschillende personen verschillende rechten nodig hebben binnen dezelfde applicatie. Een gateway kan niet uitdrukken dat "Ana de dashboards mag bewerken en Bo ze alleen mag inzien". Als de leverancier een SSO-abonnement aanbiedt, is de koppeling tussen groepen en rollen meestal waar u daadwerkelijk voor betaalt; dit namaken met headers en proxy-regels is kwetsbaarder dan ervoor betalen. Het prijsmodel achter die SSO-abonnementen is het lezen waard voordat u een beslissing neemt.

Twee andere situaties wijzen in dezelfde richting. Compliance-werkzaamheden die per gebruiker audit-logs binnen de applicatie vereisen, accepteren een toegangslog van een proxy niet als bewijslast. Bovendien zal elke applicatie met een mobiele of desktop-client die geen browser-cookies meestuurt, bij elk verzoek conflicteren met de gateway.

FAQ

Wat is forward auth?

Forward auth is een patroon waarbij de reverse proxy voor elk inkomend verzoek een aparte authenticatieservice raadpleegt voordat het verzoek wordt doorgestuurd naar de upstream-service. De proxy stuurt de request headers naar een endpoint zoals /oauth2/auth en leest de statuscode uit. 202 betekent toegestaan, waardoor het oorspronkelijke verzoek wordt doorgezet naar de applicatie. 401 betekent geen sessie, waarna de proxy de browser doorverwijst naar een inlogpagina. Nginx implementeert dit met de auth_request-richtlijn, Traefik met de forwardAuth-middleware en Caddy met forward_auth.

Waarom stuurt oauth2-proxy mij in een lus terug naar de inlogpagina?

Het callback-verzoek bereikte oauth2-proxy zonder de bijbehorende CSRF-cookie, waardoor oauth2-proxy het proces opnieuw start. Het serverlogboek toont No cookies were found in OAuth callback. en de browser toont Login Failed: Unable to find a valid CSRF token. Please try again.. De meest voorkomende oorzaak is cookie_secure = true op een site die de browser via onversleuteld HTTP heeft bereikt, omdat een browser geen Secure-cookie opslaat op een http://-origin. De op één na meest voorkomende oorzaak is een cookie_domains-waarde die de hostnaam in de adresbalk niet dekt.

Hoe laat ik een API-client of webhook door oauth2-proxy heen?

Gebruik skip_auth_routes met een verankerde reguliere expressie, eventueel beperkt tot één HTTP-methode, bijvoorbeeld POST=^/webhook/. Als uw API-clients al beschikken over JWT's die door dezelfde provider zijn uitgegeven, accepteert skip_jwt_bearer_tokens = true deze tokens in plaats van een cookie en blijft het pad beschermd. Alles wat in skip_auth_routes staat vermeld, is voor iedereen ongeauthenticeerd; houd elke expressie daarom zo specifiek mogelijk als de aanroeper toestaat.

Geeft oauth2-proxy de applicatie rechten per gebruiker?

Nee. Het is een toegangspoort, geen autorisatiesysteem. Het bepaalt wie de applicatie bereikt, en iedereen die de applicatie bereikt ziet er voor de applicatie identiek uit, tenzij die applicatie identiteitsheaders uitleest en deze koppelt aan accounts. Grafana kan dit via de auth.proxy-instellingen. De meeste zelfgehoste applicaties kunnen dit niet, waardoor elke persoon die voorbij de poort komt dezelfde identiteit deelt waarmee de applicatie draait.

Kan iemand oauth2-proxy omzeilen door zelf de identiteitsheader in te stellen?

Ja, als diegene de applicatie rechtstreeks kan bereiken. De identiteit komt aan als een standaard header zoals X-Auth-Request-Email, en de applicatie vertrouwt alles wat deze ontvangt. Iedereen die een verbinding kan openen naar de applicatiepoort, kan die header meesturen en zich voordoen als elke willekeurige gebruiker. Bind de applicatie aan 127.0.0.1, of houd deze op een intern Docker-netwerk zonder gepubliceerde poort, en bevestig dit met sudo ss -tlnp.

#oauth2-proxy#sso#oidc#reverse-proxy#forward-auth