Logg ut i et OAuth-sikret program

1. Oversikt

I denne raske opplæringen skal vi vise hvordan vi kan legge til avloggingsfunksjonalitet i et OAuth Spring Security-program.

Vi får se et par måter å gjøre dette på. Først får vi se hvordan vi logger ut Keycloak-brukeren vår fra OAuth-applikasjonen som beskrevet i Opprette en REST API med OAuth2, og deretter bruke Zuul-proxyen vi så tidligere.

Vi bruker OAuth-stakken i Spring Security 5. Hvis du vil bruke Spring Security OAuth-arven, kan du ta en titt på denne forrige artikkelen: Logg ut i et OAuth-sikret program (ved hjelp av den eldre stakken).

2. Logg ut med Front-End-applikasjon

Siden tilgangstokenene administreres av autorisasjonsserveren, må de ugyldiggjøres på dette nivået. De nøyaktige trinnene for å gjøre dette vil være litt forskjellige, avhengig av autorisasjonsserveren du bruker.

I eksempelet vårt, i henhold til Keycloak-dokumentasjonen, for å logge ut direkte fra et nettleserapplikasjon, kan vi omdirigere nettleseren til // auth-server / auth / realms / {realm-name} / protocol / openid-connect / logout? redirect_uri = encodedRedirectUri.

I tillegg til å sende viderekoblings-URI, må vi også passere en id_token_hint til Keycloaks Logout-sluttpunkt. Dette skal bære kodet id_token verdi.

La oss huske hvordan vi hadde reddet tilgangstoken, vil vi på samme måte lagre id_token også:

saveToken (token) {var expireDate = new Date (). getTime () + (1000 * token.expires_in); Cookie.set ("access_token", token.access_token, expireDate); Cookie.set ("id_token", token.id_token, expireDate); this._router.navigate (['/']); } 

Det er viktig at for å få ID-token i autorisasjonsserverens svarelast, bør vi inkludere openid i omfangsparameteren.

La oss nå se utloggingsprosessen i aksjon.

Vi endrer funksjonen vår Logg ut i App-tjeneste:

logout () {let token = Cookie.get ('id_token'); Cookie.delete ('access_token'); Cookie.delete ('id_token'); la logoutURL = "// localhost: 8083 / auth / realms / baeldung / protocol / openid-connect / logout? id_token_hint =" + token + "& post_logout_redirect_uri =" + this.redirectUri; window.location.href = logoutURL; }

Bortsett fra viderekoblingen, vi må også forkaste Access- og ID-tokens som vi hadde fått fra autorisasjonsserveren.

Derfor, i koden ovenfor, slettet vi først tokens, og omdirigerte nettleseren til Keycloak's Logg ut API.

Spesielt passerte vi i omdirigerings-URI som // lokal vert: 8089 / - den vi bruker i hele applikasjonen - så vi havner på destinasjonssiden etter å ha logget av.

Slette Access, ID og Refresh Tokens som tilsvarer den gjeldende økten, utføres på slutten av Authorization Server. Nettleserprogrammet vårt hadde ikke lagret Refresh Token i det hele tatt.

3. Logg ut med Zuul Proxy

I en tidligere artikkel om håndtering av oppdateringstokenet, har vi satt opp applikasjonen vår for å kunne oppdatere Access Token ved hjelp av et Refresh Token. Denne implementeringen bruker en Zuul-proxy med tilpassede filtre.

Her ser vi hvordan du legger til avloggingsfunksjonaliteten til ovennevnte.

Denne gangen bruker vi en annen Keycloak API for å logge ut en bruker. Vi påkaller POST på Logg ut sluttpunkt for å logge ut en økt via en ikke-nettleserinnkalling, i stedet for URL-omdirigering vi brukte i forrige avsnitt.

3.1. Definer rute for utlogging

Til å begynne med, la oss legge til en annen rute til proxyen i vår application.yml:

zuul: ruter: // ... auth / refresh / revoke: path: / auth / refresh / revoke / ** sensitiveHeaders: url: // localhost: 8083 / auth / realms / baeldung / protocol / openid-connect / logout / / autent / oppdater rute

Faktisk la vi til en underrute til den allerede eksisterende godkjenne / oppdatere. Det er viktig at vi legger til underruten før hovedruten, ellers vil Zuul alltid kartlegge URL-en til hovedruten.

Vi la til en underrute i stedet for en hovedrute for å ha tilgang til bare HTTP refreshToken informasjonskapsel, som ble satt til å ha en veldig begrenset vei som / auth / refresh (og dens underveier). Vi får se hvorfor vi trenger informasjonskapselen i neste avsnitt.

3.2. POST til autorisasjonsserverens /Logg ut

La oss nå forbedre CustomPreZuulFilter implementering for å fange opp / godkjenne / oppdatere / tilbakekalle URL og legg til nødvendig informasjon som skal sendes videre til autorisasjonsserveren.

Skjemaparametrene som kreves for utlogging, ligner på forespørselen om oppdateringstoken, bortsett fra at det ikke er tilskuddstype:

@Komponent offentlig klasse CustomPostZuulFilter utvider ZuulFilter {// ... @Override public Object run () {// ... if (requestURI.contains ("auth / refresh / revoke")) {String cookieValue = extractCookie (req, " refreshToken "); String formParams = String.format ("client_id =% s & client_secret =% s & refresh_token =% s", CLIENT_ID, CLIENT_SECRET, cookieValue); bytes = formParams.getBytes ("UTF-8"); } // ...}}

Her hentet vi ganske enkelt ut refreshToken informasjonskapsel og sendt inn påkrevd formParams.

3.3. Fjern Refresh Token

Når du tilbakekaller Access Token ved hjelp av Logg ut omdirigering som vi så tidligere, blir Refresh Token tilknyttet det også ugyldiggjort av autorisasjonsserveren.

I dette tilfellet er imidlertid httpBare informasjonskapsel forblir satt på klienten. Gitt at vi ikke kan fjerne det via JavaScript, må vi fjerne det fra serversiden.

For det, la oss legge til CustomPostZuulFilter implementering som avlytter / godkjenne / oppdatere / tilbakekalle URL slik at den vil fjern refreshToken kjeks når du møter denne URL:

@Component public class CustomPostZuulFilter utvider ZuulFilter {// ... @Override public Object run () {// ... String requestMethod = ctx.getRequest (). GetMethod (); if (requestURI.contains ("auth / refresh / revoke")) {Cookie cookie = new Cookie ("refreshToken", ""); cookie.setMaxAge (0); ctx.getResponse (). addCookie (informasjonskapsel); } // ...}}

3.4. Fjern Access Token fra Angular Client

Foruten å oppheve Refresh Token, har tilgangstoken informasjonskapsel må også fjernes fra klientsiden.

La oss legge til en metode i Angular-kontrolleren som tømmer tilgangstoken informasjonskapsel og kaller / godkjenne / oppdatere / tilbakekalle POST-kartlegging:

logout () {let headers = new HttpHeaders ({'Content-type': 'application / x-www-form-urlencoded; charset = utf-8'}); this._http.post ('auth / refresh / revoke', {}, {headers: headers}). abonner (data => {Cookie.delete ('access_token'); window.location.href = '// localhost: 8089 / ';}, err => alarm (' Kunne ikke logge ut ')); }

Denne funksjonen kalles når du klikker på Logout-knappen:

Logg ut

4. Konklusjon

I denne raske, men grundige opplæringen, har vi vist hvordan vi kan logge ut en bruker fra en OAuth sikret applikasjon og ugyldiggjør brukerens tokens.

Den fulle kildekoden til eksemplene finner du på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found