Spring Security OAuth2 - egyszerű token visszavonás (a Spring Security OAuth örökölt verem használatával)

1. Áttekintés

Ebben a gyors bemutatóban bemutatjuk, hogyan vonhatjuk vissza az OAuth-hitelesítési kiszolgáló végrehajtása Tavaszi biztonság.

Amikor a felhasználó kijelentkezik, a tokenjét nem távolítja el azonnal a token tárolóból; ehelyett addig marad érvényben, amíg önmagában le nem jár.

Tehát a token visszavonása azt jelenti, hogy eltávolítja a tokent a token tárolóból. A szabványos token megvalósítását a keretrendszerben fogjuk lefedni, nem a JWT tokenekre.

jegyzet: ez a cikk a Spring OAuth örökölt projektet használja.

2. A TokenStore

Először állítsuk be a token boltot; használjuk a JdbcTokenStore, a kísérő adatforrással együtt:

@Bean public TokenStore tokenStore () {return new JdbcTokenStore (dataSource ()); } @Bean public DataSource dataSource () {DriverManagerDataSource dataSource = új 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")); return dataSource; }

3. Az DefaultTokenServices Bab

Az összes jelzőt kezelő osztály a DefaultTokenServices - és babként kell meghatározni a konfigurációnkban:

@Bean @Primary public DefaultTokenServices tokenServices () {DefaultTokenServices defaultTokenServices = new DefaultTokenServices (); defaultTokenServices.setTokenStore (tokenStore ()); defaultTokenServices.setSupportRefreshToken (true); return defaultTokenServices; }

4. A tokenek listájának megjelenítése

Adminisztrációs célokból állítsunk be egy módot a jelenleg érvényes tokenek megtekintésére.

Hozzáférünk a TokenStore vezérlőben, és töltse le a jelenleg tárolt tokenek egy adott ügyfél-azonosítóhoz:

@Resource (név = "tokenStore") TokenStore tokenStore; @RequestMapping (metódus = RequestMethod.GET, value = "/ tokens") @ResponseBody public list getTokens () {List tokenValues ​​= new ArrayList (); Gyűjtemény tokenek = tokenStore.findTokensByClientId ("sampleClientId"); if (tokenek! = null) {for (OAuth2AccessToken token: tokenek) {tokenValues.add (token.getValue ()); }} return tokenValues; }

5. Hozzáférési token visszavonása

A token érvénytelenítéséhez felhasználjuk a revokeToken () API a ConsumerTokenServices felület:

@Resource (név = "tokenServices") ConsumerTokenServices tokenServices; @RequestMapping (metódus = RequestMethod.POST, érték = "/tokens/revoke/{tokenId:.*}") @ResponseBody nyilvános karakterlánc revokeToken (@PathVariable String tokenId) {tokenServices.revokeToken (tokenId); return tokenId; }

Természetesen ez egy nagyon érzékeny művelet, ezért vagy csak belsőleg kell használnunk, vagy nagy gondossággal kell eljárnunk a megfelelő biztonság mellett.

6. A front-end

A példánk elülső részén megjelenítjük az érvényes tokenek listáját, a visszavonási kérelmet benyújtó bejelentkezett felhasználó által használt tokent és egy mezőt, ahol a felhasználó megadhatja a visszavonni kívánt tokent:

$ scope.revokeToken = $ resource ("// localhost: 8082 / spring-security-oauth-resource / tokens / revoke /: tokenId", {tokenId: '@ tokenId'}); $ scope.tokens = $ resource ("// localhost: 8082 / spring-security-oauth-resource / tokens"); $ hatókör.getTokens = function () {$ hatókör.tokenList = $ hatókör.tokens.query (); } $ hatókör.revokeAccessToken = function () {if ($ hatókör.tokenToRevoke && $ hatókör.tokenToRevoke.length! = 0) {$ hatókör.revokeToken.save ({tokenId: $ hatókör.tokenToRevoke}); $ rootScope.message = "Token:" + $ scope.tokenToRevoke + "visszavonva!"; $ scope.tokenToRevoke = ""; }}

Ha a felhasználó megpróbálja újra visszavont tokent használni, akkor egy „érvénytelen token” hibát kap 401-es állapotkóddal.

7. A frissítési token visszavonása

A frissítési token új hozzáférési token megszerzésére használható. Amikor egy hozzáférési tokent visszavonnak, a vele kapott frissítési token érvénytelen lesz.

Ha magát a frissítési tokent is érvényteleníteni akarjuk, használhatjuk a módszert removeRefreshToken () osztályú JdbcTokenStore, amely eltávolítja a frissítési tokent az üzletből:

@RequestMapping (metódus = RequestMethod.POST, value = "/tokens/revokeRefreshToken/{tokenId:.*}") @ResponseBody nyilvános karakterlánc revokeRefreshToken (@PathVariable String tokenId) {if (tokenStore példány JdbcTokenStoreStore)) (( .removeRefreshToken (tokenId); } return tokenId; }

Annak tesztelésére, hogy a frissítési token a visszavonás után már nem érvényes, megírjuk a következő tesztet, amelyben megszerezünk egy hozzáférési tokent, frissítjük, majd eltávolítjuk a frissítési tokent, és megpróbáljuk újra frissíteni.

Látni fogjuk, hogy visszavonás után megkapjuk a válasz hibát: „érvénytelen frissítési token”:

public class TokenRevocationLiveTest {private String refreshToken; privát karakterlánc getAccessToken (String clientId, String felhasználónév, String jelszó) {Map params = new HashMap (); params.put ("grant_type", "jelszó"); params.put ("client_id", clientId); params.put ("felhasználónév", felhasználónév); params.put ("jelszó", jelszó); Válaszválasz = RestAssured.given (). Auth (). megelőző (). basic (clientId, "titkos"). és (). a (). paramokkal (paramokkal). mikor (). post ("// localhost: 8081 / spring-security-oauth-server / oauth / token"); refreshToken = response.jsonPath (). getString ("refresh_token"); return response.jsonPath (). getString ("access_token"); } privát karakterlánc getRefreshToken (String clientId) {Map params = new HashMap (); params.put ("grant_type", "refresh_token"); params.put ("client_id", clientId); params.put ("refresh_token", refreshToken); Válaszválasz = RestAssured.given (). Auth () .preemptive (). Basic (clientId, "secret"). És (). A (). Params (params) .when (). Post ("// localhost: 8081 / spring-security-oauth-server / oauth / token "); return response.jsonPath (). getString ("access_token"); } private void autorizeClient (String clientId) {Térképparamek = új HashMap (); params.put ("response_type", "code"); params.put ("client_id", clientId); params.put ("hatókör", "olvasás, írás"); Válaszválasz = RestAssured.given (). Auth (). Preemptive () .basic (clientId, "secret"). És (). (). Paraméterekkel (paraméterek). mikor (). post ("// localhost: 8081 / spring-security-oauth-server / oauth / autorizálás"); } @Test public void givenUser_whenRevokeRefreshToken_thenRefreshTokenInvalidError () {String accessToken1 = iegūtAccessToken ("fooClientIdPassword", "john", "123"); Karakterlánc accessToken2 = iegūtAccessToken ("fooClientIdPassword", "tom", "111"); authorizeClient ("fooClientIdPassword"); Karakterlánc accessToken3 = iegūtRefreshToken ("fooClientIdPassword"); authorizeClient ("fooClientIdPassword"); Válasz refreshTokenResponse = RestAssured.given (). header ("Engedélyezés", "Viselő" + accessToken3) .get ("// localhost: 8082 / spring-security-oauth-resource / tokens"); assertEquals (200, refreshTokenResponse.getStatusCode ()); Válasz revokeRefreshTokenResponse = RestAssured.given () .header ("Engedélyezés", "Bemutató" + accessToken1) .post ("// localhost: 8082 / spring-security-oauth-erőforrás / tokenek / revokeRefreshToken /" + refreshToken); assertEquals (200, revokeRefreshTokenResponse.getStatusCode ()); Karakterlánc accessToken4 = iegūtRefreshToken ("fooClientIdPassword"); authorizeClient ("fooClientIdPassword"); Válasz refreshTokenResponse2 = RestAssured.given () .header ("Engedélyezés", "Viselő" + accessToken4) .get ("// localhost: 8082 / spring-security-oauth-erőforrás / tokenek"); assertEquals (401, refreshTokenResponse2.getStatusCode ()); }}

8. Következtetés

Ebben az oktatóanyagban bemutattuk, hogyan lehet visszavonni az OAuth hozzáférési tokent és az Oauth frissítési tokent.

Ennek az oktatóanyagnak a megvalósítása megtalálható a GitHub projektben.


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