Spring Security OAuth2 - jednoduché zrušenie tokenu (pomocou staršieho zásobníka Spring Security OAuth)

1. Prehľad

V tomto rýchlom výučbe si ukážeme, ako môžeme odvolať tokeny poskytnuté pomocou Autorizačný server OAuth implementované s Jarná bezpečnosť.

Keď sa používateľ odhlási, jeho token sa neodstráni okamžite z úložiska tokenov; zostáva v platnosti, kým nevyprší jeho platnosť.

Odvolanie tokenu bude teda znamenať odstránenie tohto tokenu z úložiska tokenov. Pokryjeme štandardnú implementáciu tokenov v rámci, nie tokeny JWT.

Poznámka: tento článok využíva starší projekt Spring OAuth.

2. The TokenStore

Najskôr nastavíme obchod s tokenmi; použijeme a JdbcTokenStorespolu so sprievodným zdrojom údajov:

@Bean public TokenStore tokenStore () {vrátiť nový JdbcTokenStore (dataSource ()); } @Bean public DataSource dataSource () {DriverManagerDataSource dataSource = nový 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")); vrátiť dátový zdroj; }

3. The DefaultTokenServices Bean

Trieda, ktorá narába so všetkými žetónmi, je DefaultTokenServices - a musí byť v našej konfigurácii definovaný ako fazuľa:

@Bean @Primary public DefaultTokenServices tokenServices () {DefaultTokenServices defaultTokenServices = nový DefaultTokenServices (); defaultTokenServices.setTokenStore (tokenStore ()); defaultTokenServices.setSupportRefreshToken (true); vrátiť defaultTokenServices; }

4. Zobrazenie zoznamu tokenov

Na účely správcu tiež nastavíme spôsob zobrazenia aktuálne platných tokenov.

Pristúpime k TokenStore v radiči a načítať aktuálne uložené tokeny pre zadané ID klienta:

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

5. Odvolanie prístupového tokenu

Na zneplatnenie tokenu použijeme revokeToken () API z ConsumerTokenServices rozhranie:

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

Jedná sa samozrejme o veľmi citlivú operáciu, takže by sme ju mali používať iba interne, alebo venovať zvýšenú pozornosť jej vystaveniu so zabezpečeným náležitým zabezpečením.

6. Klientske rozhranie

Pre klientske rozhranie nášho príkladu zobrazíme zoznam platných tokenov, token, ktorý aktuálne používa prihlásený používateľ, ktorý podáva žiadosť o odvolanie, a pole, kde môže používateľ zadať token, ktorý chce odvolať:

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

Ak sa používateľ pokúsi znova použiť odvolaný token, zobrazí sa mu chyba „neplatný token“ so stavovým kódom 401.

7. Odvolanie obnovovacieho tokenu

Obnovovací token možno použiť na získanie nového prístupového tokenu. Kedykoľvek je prístupový token odvolaný, obnovovací token, ktorý bol s ním prijatý, je zneplatnený.

Ak chceme zneplatniť aj samotný obnovovací token, môžeme použiť metódu removeRefreshToken () triedy JdbcTokenStore, ktorý odstráni obnovovací token z obchodu:

@RequestMapping (method = RequestMethod.POST, value = "/tokens/revokeRefreshToken/{tokenId:.*}") @ResponseBody verejný reťazec revokeRefreshToken (@PathVariable String tokenId) {if (tokenStore instanceof JdbcTokenStore) {(en) .removeRefreshToken (tokenId); } vratit tokenId; }

Aby sme vyskúšali, či obnovovací token po odvolaní už nie je platný, napíšeme nasledujúci test, v ktorom získame prístupový token, obnovíme ho, potom odstránime obnovovací token a pokúsime sa ho obnoviť znova.

Uvidíme, že po odvolaní dostaneme chybu odpovede: „invalid refresh token“:

verejná trieda TokenRevocationLiveTest {private String refreshToken; private String obtainAccessToken (String clientId, String username, String password) {Map params = new HashMap (); params.put ("grant_type", "heslo"); params.put ("client_id", clientId); params.put ("užívateľské meno", užívateľské meno); params.put ("heslo", heslo); Odozva na odpoveď = RestAssured.given (). Auth (). preventívne (). základné (clientId, "tajné"). a (). s (). params (params). when (). post ("// localhost: 8081 / spring-security-oauth-server / oauth / token"); refreshToken = response.jsonPath (). getString ("refresh_token"); návrat 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); Response response = RestAssured.given (). Auth () .preemptive (). Basic (clientId, "secret"). A (). S (). Params (params) .when (). Post ("// localhost: 8081 / spring-security-oauth-server / oauth / token "); návrat response.jsonPath (). getString ("access_token"); } private void authorizeClient (String clientId) {Map params = new HashMap (); params.put ("response_type", "code"); params.put ("client_id", clientId); params.put ("rozsah", "čítať, písať"); Reakcia odpovede = RestAssured.given (). Auth (). Preemptive () .basic (clientId, "tajný"). A (). S (). Params (params). when (). post ("// localhost: 8081 / spring-security-oauth-server / oauth / authorize"); } @Test public void givenUser_whenRevokeRefreshToken_thenRefreshTokenInvalidError () {String accessToken1 = obtainAccessToken ("fooClientIdPassword", "john", "123"); Reťazec accessToken2 = obtainAccessToken ("fooClientIdPassword", "tom", "111"); authorizeClient ("fooClientIdPassword"); Reťazec accessToken3 = obtainRefreshToken ("fooClientIdPassword"); authorizeClient ("fooClientIdPassword"); Response refreshTokenResponse = RestAssured.given (). hlavička ("Autorizácia", "Nositeľ" + accessToken3) .get ("// localhost: 8082 / spring-security-oauth-resource / tokens"); assertEquals (200, refreshTokenResponse.getStatusCode ()); Response revokeRefreshTokenResponse = RestAssured.given () .header ("Authorization", "Bearer" + accessToken1) .post ("// localhost: 8082 / spring-security-oauth-resource / tokens / revokeRefreshToken /" + refreshToken); assertEquals (200, revokeRefreshTokenResponse.getStatusCode ()); Reťazec accessToken4 = obtainRefreshToken ("fooClientIdPassword"); authorizeClient ("fooClientIdPassword"); Response refreshTokenResponse2 = RestAssured.given () .header ("Authorization", "Bearer" + accessToken4) .get ("// localhost: 8082 / spring-security-oauth-resource / tokens"); assertEquals (401, refreshTokenResponse2.getStatusCode ()); }}

8. Záver

V tomto tutoriáli sme si ukázali, ako odvolať prístupový token OAuth a obnovovací token Oauth.

Implementáciu tohto tutoriálu nájdete v projekte GitHub.


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