Spring Security OAuth2 - Enkel token tilbakekalling (ved bruk av Spring Security OAuth arvstabel)

1. Oversikt

I denne raske opplæringen vil vi illustrere hvordan vi kan tilbakekalle tokens gitt av en OAuth autorisasjonsserver implementert med Vårsikkerhet.

Når en bruker logger av, blir ikke tokenet deres umiddelbart fjernet fra tokenbutikken; i stedet forblir den gyldig til den utløper alene.

Og så, tilbakekalling av et token vil bety at du fjerner dette tokenet fra tokenbutikken. Vi vil dekke standard tokenimplementering i rammeverket, ikke JWT-tokens.

Merk: denne artikkelen bruker Spring OAuth arvprosjekt.

2. Den TokenStore

Først, la oss sette opp tokenbutikken; vi bruker en JdbcTokenStore, sammen med den medfølgende datakilden:

@Bean offentlig TokenStore tokenStore () {returner ny JdbcTokenStore (dataSource ()); } @Bean public DataSource dataSource () {DriverManagerDataSource dataSource = new DriverManagerDataSource (); dataSource.setDriverClassName (env.getProperty ("jdbc.driverClassName")); dataSource.setUrl (env.getProperty ("jdbc.url")); dataSource.setUsername (env.getProperty ("jdbc.user")); dataSource.setPassword (env.getProperty ("jdbc.pass")); returner datakilde; }

3. Den DefaultTokenServices Bønne

Klassen som håndterer alle tokens er DefaultTokenServices - og må defineres som en bønne i vår konfigurasjon:

@Bean @ Primær offentlig DefaultTokenServices tokenServices () {DefaultTokenServices defaultTokenServices = ny DefaultTokenServices (); defaultTokenServices.setTokenStore (tokenStore ()); defaultTokenServices.setSupportRefreshToken (true); returner defaultTokenServices; }

4. Vise listen over poletter

For adminformål, la oss også sette opp en måte å vise de nåværende gyldige tokens på.

Vi får tilgang til TokenStore i en kontroller, og hente de lagrede tokens for en spesifisert klient-ID:

@Resource (name = "tokenStore") TokenStore tokenStore; @RequestMapping (method = RequestMethod.GET, value = "/ tokens") @ResponseBody public List getTokens () {List tokenValues ​​= new ArrayList (); Collection tokens = tokenStore.findTokensByClientId ("sampleClientId"); hvis (tokens! = null) {for (OAuth2AccessToken token: tokens) {tokenValues.add (token.getValue ()); }} returner tokenValues; }

5. Å tilbakekalle et adgangstoken

For å ugyldiggjøre et token, bruker vi revokeToken () API fra ConsumerTokenServices grensesnitt:

@Resource (name = "tokenServices") ConsumerTokenServices tokenServices; @RequestMapping (method = RequestMethod.POST, value = "/tokens/revoke/{tokenId:.*}") @ResponseBody public String revokeToken (@PathVariable String tokenId) {tokenServices.revokeToken (tokenId); return tokenId; }

Selvfølgelig er dette en veldig sensitiv operasjon, så vi bør enten bare bruke den internt, eller så bør vi være nøye med å utsette den med riktig sikkerhet på plass.

6. Frontend

For frontenden av eksemplet vårt viser vi listen over gyldige tokens, tokenet som for øyeblikket brukes av den påloggede brukeren som gjør tilbakekallingsforespørselen, og et felt der brukeren kan angi tokenet de ønsker å tilbakekalle:

$ scope.revokeToken = $ ressurs ("// localhost: 8082 / spring-security-oauth-resource / tokens / revoke /: tokenId", {tokenId: '@ tokenId'}); $ scope.tokens = $ resource ("// localhost: 8082 / spring-security-oauth-resource / tokens"); $ scope.getTokens = funksjon () {$ scope.tokenList = $ scope.tokens.query (); } $ scope.revokeAccessToken = funksjon () {if ($ scope.tokenToRevoke && $ scope.tokenToRevoke.length! = 0) {$ scope.revokeToken.save ({tokenId: $ scope.tokenToRevoke}); $ rootScope.message = "Token:" + $ scope.tokenToRevoke + "ble tilbakekalt!"; $ scope.tokenToRevoke = ""; }}

Hvis en bruker prøver å bruke et tilbakekalt token igjen, vil de motta en 'ugyldig token' -feil med statuskode 401.

7. Å tilbakekalle Refresh Token

Oppdateringstokenet kan brukes til å skaffe et nytt tilgangstoken. Hver gang et tilgangstoken tilbakekalles, blir oppdateringstokenet som ble mottatt med det ugyldiggjort.

Hvis vi også vil ugyldiggjøre oppdateringstokenet, kan vi bruke metoden removeRefreshToken () av klassen JdbcTokenStore, som fjerner oppdateringstokenet fra butikken:

@RequestMapping (method = RequestMethod.POST, value = "/tokens/revokeRefreshToken/{tokenId:.*}") @ResponseBody public String revokeRefreshToken (@PathVariable String tokenId) {if (tokenStore-forekomst av JdbcTokenStore) ((JokeBoreStore)) .removeRefreshToken (tokenId); } returner tokenId; }

For å teste at oppdateringstoken ikke lenger er gyldig etter at den er tilbakekalt, skriver vi følgende test der vi får tilgangstoken, oppdaterer den, fjerner oppdateringstoken og prøver å oppdatere den igjen.

Vi vil se at etter tilbakekalling vil vi motta svarfeilen: "ugyldig oppdateringstoken":

offentlig klasse TokenRevocationLiveTest {private String refreshToken; private String obtainAccessToken (String clientId, String brukernavn, String passord) {Map params = new HashMap (); params.put ("grant_type", "password"); params.put ("client_id", clientId); params.put ("brukernavn", brukernavn); params.put ("passord", passord); Svarrespons = RestAssured.given (). Auth (). preemptive (). basic (clientId, "secret"). og (). with (). params (params). når (). post ("// localhost: 8081 / spring-security-oauth-server / oauth / token"); refreshToken = respons.jsonPath (). getString ("refresh_token"); return response.jsonPath (). getString ("access_token"); } private String obtainRefreshToken (String clientId) {Map params = new HashMap (); params.put ("grant_type", "refresh_token"); params.put ("client_id", clientId); params.put ("refresh_token", refreshToken); Svarrespons = RestAssured.given (). Auth (). Forebyggende (). Basic (clientId, "hemmelig"). Og (). Med (). Params (params) .when (). Post ("// localhost: 8081 / spring-security-oauth-server / oauth / token "); return response.jsonPath (). getString ("access_token"); } private void authorizeClient (String clientId) {Map params = new HashMap (); params.put ("respons_type", "kode"); params.put ("client_id", clientId); params.put ("omfang", "lese, skrive"); Svarrespons = RestAssured.given (). Auth (). Preemptive () .basic (clientId, "secret"). Og (). With (). Params (params). når (). post ("// localhost: 8081 / spring-security-oauth-server / oauth / authorize"); } @Test offentlig tomrom gittUser_whenRevokeRefreshToken_thenRefreshTokenInvalidError () {String accessToken1 = obtainAccessToken ("fooClientIdPassword", "john", "123"); Streng accessToken2 = obtainAccessToken ("fooClientIdPassword", "tom", "111"); authorizeClient ("fooClientIdPassword"); Streng accessToken3 = obtainRefreshToken ("fooClientIdPassword"); authorizeClient ("fooClientIdPassword"); Svar refreshTokenResponse = RestAssured.given (). header ("Authorization", "Bearer" + accessToken3) .get ("// localhost: 8082 / spring-security-oauth-resource / tokens"); assertEquals (200, refreshTokenResponse.getStatusCode ()); Svar revokeRefreshTokenResponse = RestAssured.given () .header ("Authorization", "Bearer" + accessToken1) .post ("// localhost: 8082 / spring-security-oauth-resource / tokens / revokeRefreshToken /" + refreshToken); assertEquals (200, revokeRefreshTokenResponse.getStatusCode ()); Streng accessToken4 = obtainRefreshToken ("fooClientIdPassword"); authorizeClient ("fooClientIdPassword"); Svar refreshTokenResponse2 = RestAssured.given () .header ("Authorization", "Bearer" + accessToken4) .get ("// localhost: 8082 / spring-security-oauth-resource / tokens"); assertEquals (401, refreshTokenResponse2.getStatusCode ()); }}

8. Konklusjon

I denne opplæringen har vi demonstrert hvordan du kan tilbakekalle et OAuth-tilgangstoken og et Oauth-oppdateringstoken.

Implementeringen av denne veiledningen finner du i GitHub-prosjektet.


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