Spring Security OAuth2 - ביטול אסימון פשוט (באמצעות מחסנית מורשת Spring Security OAuth)

1. סקירה כללית

במדריך מהיר זה נמחיש כיצד אנו יכולים לבטל אסימונים המוענקים על ידי שרת אישור OAuth מיושם עם אביב ביטחון.

כאשר משתמש מתנתק, האסימון שלו לא מוסר מיד מחנות האסימונים; במקום זאת, הוא נשאר בתוקף עד שהוא יפוג לבדו.

וכך, ביטול אסימון פירושו להסיר את האסימון מחנות האסימונים. אנו נכסה את יישום האסימונים הסטנדרטיים במסגרת, ולא אסימוני JWT.

הערה: מאמר זה משתמש בפרויקט מורשת Spring OAuth.

2. ה TokenStore

ראשית, בואו נקים את חנות האסימונים; נשתמש ב- JdbcTokenStoreיחד עם מקור הנתונים הנלווה:

@Bean TokenStore ציבורי tokenStore () {להחזיר JdbcTokenStore חדש (dataSource ()); } @Bean DataSource ציבורי DataSource () {DriverManagerDataSource dataSource = חדש 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")); להחזיר dataSource; }

3. ה DefaultTokenServices אפונה

הכיתה המטפלת בכל האסימונים היא ה DefaultTokenServices - ויש להגדירו כשעועית בתצורה שלנו:

@Bean @Primary public DefaultTokenServices tokenServices () {DefaultTokenServices defaultTokenServices = DefaultTokenServices חדש (); defaultTokenServices.setTokenStore (tokenStore ()); defaultTokenServices.setSupportRefreshToken (נכון); החזר defaultTokenServices; }

4. הצגת רשימת האסימונים

למטרות אדמיניסטרציה, בואו נקבע דרך להציג את האסימונים החוקיים כרגע.

ניגש ל- TokenStore בבקר, ואחזר את האסימונים המאוחסנים כעת עבור מזהה לקוח מוגדר:

@Resource (name = "tokenStore") TokenStore tokenStore; @RequestMapping (method = RequestMethod.GET, value = "/ tokens") @ResponseBody רשימת משתמשים getTokens () {List tokenValues ​​= ArrayList new (); אסימונים לאוסף = tokenStore.findTokensByClientId ("sampleClientId"); אם (אסימונים! = null) {עבור (אסימון OAuth2AccessToken: אסימונים) {tokenValues.add (token.getValue ()); }} להחזיר tokenValues; }

5. ביטול אסימון גישה

על מנת לפסול אסימון, נשתמש ב- revokeToken () ממשק API מה- ConsumerTokenServices מִמְשָׁק:

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

כמובן שמדובר בפעולה רגישה מאוד ולכן עלינו להשתמש בה רק באופן פנימי, או שנקפיד לחשוף אותה עם האבטחה הראויה במקום.

6. חזית הקצה

עבור החלק הקדמי של הדוגמה שלנו, נציג את רשימת האסימונים החוקיים, האסימון המשמש כעת את המשתמש המחובר שמגיש את בקשת הביטול, ושדה שבו המשתמש יכול להזין את האסימון שברצונו לבטל:

$ 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 = פונקציה () {$ scope.tokenList = $ scope.tokens.query (); } $ scope.revokeAccessToken = פונקציה () {if ($ scope.tokenToRevoke && $ scope.tokenToRevoke.length! = 0) {$ scope.revokeToken.save ({tokenId: $ scope.tokenToRevoke}); $ rootScope.message = "אסימון:" + $ scope.tokenToRevoke + "בוטל!"; $ scope.tokenToRevoke = ""; }}

אם משתמש ינסה להשתמש שוב באסימון שבוטל, הוא יקבל שגיאת 'אסימון לא חוקי' עם קוד המצב 401.

7. ביטול אסימון הרענון

ניתן להשתמש באסימון הרענון כדי להשיג אסימון גישה חדש. בכל פעם שאסימון גישה מבוטל, אסימון הרענון שהתקבל איתו אינו מבוטל.

אם אנו רוצים לפסול גם את אסימון הרענון עצמו, נוכל להשתמש בשיטה removeRefreshToken () של הכיתה JdbcTokenStore, שיסיר את אסימון הרענון מהחנות:

@RequestMapping (method = RequestMethod.POST, value = "/tokens/revokeRefreshToken/{tokenId:.*}") @ResponseBody public String revokeRefreshToken (@PathVariable String tokenId) {if (tokenStore instance of JdbcTokenStore) {(JokenboreStore) .removeRefreshToken (tokenId); } חזור tokenId; }

על מנת לבדוק שאסימון הרענון אינו תקף עוד לאחר ביטולו, נכתוב את המבחן הבא, בו נקבל אסימון גישה, נרענן אותו, ואז נסיר את אסימון הרענון וננסה לרענן אותו שוב.

נראה שלאחר ביטול נקבל את שגיאת התגובה: "אסימון רענון לא חוקי":

מחלקה ציבורית TokenRevocationLiveTest {רישיון מחרוזת פרטי; מחרוזת פרטית obtainAccessToken (מחרוזת clientId, שם משתמש מחרוזת, סיסמת מחרוזת) {Map params = HashMap new (); params.put ("grant_type", "password"); params.put ("client_id", clientId); params.put ("שם משתמש", שם משתמש); params.put ("סיסמה", סיסמה); תגובת תגובה = RestAssured.given (). Auth (). מנע (). בסיסי (clientId, "סודי"). ו- (). עם (). פאראמס (פאראמס). מתי (). post ("// localhost: 8081 / spring-security-oauth-server / oauth / token"); refreshToken = response.jsonPath (). getString ("refresh_token"); return response.jsonPath (). getString ("access_token"); } מחרוזת פרטית obtainRefreshToken (מחרוזת clientId) {Map params = HashMap חדש (); params.put ("grant_type", "refresh_token"); params.put ("client_id", clientId); params.put ("refresh_token", refreshToken); תגובת תגובה = RestAssured.given (). Auth (). מונע (). Basic (clientId, "סודי"). ו- (). עם (). Params (params) .when (). Post ("// localhost: 8081 / spring-security-oauth-server / oauth / token "); return response.jsonPath (). getString ("access_token"); } חלל פרטי authorizeClient (String clientId) {Map params = HashMap new (); params.put ("response_type", "code"); params.put ("client_id", clientId); params.put ("היקף", "לקרוא, לכתוב"); תגובת תגובה = RestAssured.given (). Auth (). מונע () .basic (clientId, "סודי"). ו- (). עם (). Params (params). מתי (). post ("// localhost: 8081 / spring-security-oauth-server / oauth / authorize"); } @Test הריק ציבורי שניתן User_whenRevokeRefreshToken_thenRefreshTokenInvalidError () {String accessToken1 = obtainAccessToken ("fooClientIdPassword", "john", "123"); מחרוזת accessToken2 = obtainAccessToken ("fooClientIdPassword", "tom", "111"); authorizeClient ("fooClientIdPassword"); מחרוזת accessToken3 = obtainRefreshToken ("fooClientIdPassword"); authorizeClient ("fooClientIdPassword"); תגובה refreshTokenResponse = RestAssured.given (). כותרת ("Authorization", "Bearer" + accessToken3) .get ("// localhost: 8082 / spring-security-oauth-resource / tokens"); assertEquals (200, refreshTokenResponse.getStatusCode ()); תגובה revokeRefreshTokenResponse = RestAssured.given () .header ("Authorization", "Bearer" + accessToken1) .post ("// localhost: 8082 / spring-security-oauth-resource / tokens / revokeRefreshToken /" + refreshToken); assertEquals (200, revokeRefreshTokenResponse.getStatusCode ()); מחרוזת accessToken4 = obtainRefreshToken ("fooClientIdPassword"); authorizeClient ("fooClientIdPassword"); תגובה refreshTokenResponse2 = RestAssured.given () .header ("Authorization", "Bearer" + accessToken4) .get ("// localhost: 8082 / spring-security-oauth-resource / tokens"); assertEquals (401, refreshTokenResponse2.getStatusCode ()); }}

8. מסקנה

במדריך זה הדגמנו כיצד לבטל אסימון גישה של OAuth ואסימון רענון של Oauth.

את יישום הדרכה זו ניתן למצוא בפרויקט GitHub.


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