יציאה מיישום מאובטח של OAuth

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

במדריך מהיר זה אנו נראה כיצד אנו יכולים להוסיף פונקציונליות התנתקות ליישום OAuth Spring Security.

נראה כמה דרכים לעשות זאת. ראשית, נראה כיצד להתנתק ממשתמש Keycloak שלנו מיישום OAuth כמתואר ביצירת REST API עם OAuth2, ולאחר מכן, באמצעות ה- proxy של Zuul שראינו קודם.

נשתמש בערמת OAuth ב- Spring Security 5. אם ברצונך להשתמש בערמת מורשת OAuth מדור קודם של Spring Security, עיין במאמר הקודם: התנתק ביישום מאובטח של OAuth (באמצעות ערימת Legacy).

2. התנתקות באמצעות יישום חזיתי

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

בדוגמה שלנו, בהתאם לתיעוד Keycloak, להתנתקות ישירות מיישום דפדפן, אנו יכולים להפנות את הדפדפן ל // auth-server / auth / realms / {realm-name} / protocol / openid-connect / logout? redirect_uri = encodedRedirectUri.

לצד שליחת ה- URI להפניה מחדש, עלינו גם להעביר id_token_hint לנקודת הסיום של התנתקות של Keycloak. זה אמור לשאת את המקודד id_token ערך.

בואו ניזכר כיצד הצלנו את ה- אסימון גישה, נשמור באופן דומה את id_token גם כן:

saveToken (אסימון) {var expireDate = תאריך חדש (). getTime () + (1000 * token.expires_in); Cookie.set ("access_token", token.access_token, expireDate); Cookie.set ("id_token", token.id_token, expireDate); this._router.navigate (['/']); } 

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

עכשיו בואו נראה את תהליך ההתנתקות בפעולה.

נשנה את הפונקציה שלנו להתנתק ב שירות אפליקציות:

התנתקות () {let token = Cookie.get ('id_token'); Cookie.delete ('גישה_סימן'); Cookie.delete ('id_token'); תן ל logoutURL = "// localhost: 8083 / auth / realms / baeldung / protocol / openid-connect / logout? id_token_hint =" + token + "& post_logout_redirect_uri =" + this.redirectUri; window.location.href = logoutURL; }

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

לפיכך, בקוד לעיל מחקנו תחילה את האסימונים, ואז הפנינו את הדפדפן ל- Keycloak להתנתק ממשק API.

יש לציין שעברנו ב- URI להפניה מחדש כ- // localhost: 8089 / - זה שאנו משתמשים בו בכל היישום - כך שנגיע לדף הנחיתה לאחר התנתקות.

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

3. יציאה באמצעות Zuul Proxy

במאמר קודם בנושא טיפול באסימון הרענון, הגדרנו את היישום שלנו כדי לרענן את אסימון הגישה באמצעות אסימון רענון. יישום זה עושה שימוש ב- proxy של Zuul עם מסננים מותאמים אישית.

כאן נראה כיצד להוסיף את פונקציונליות ההתנתקות לאמור לעיל.

הפעם נשתמש ב- API נוסף של Keycloak כדי להתנתק ממשתמש. אנו נזמין את POST בתאריך להתנתק נקודת קצה כדי להתנתק מפגישה באמצעות קריאה שאינה דפדפן, במקום כתובת האתר להפניה מחדש בה השתמשנו בסעיף הקודם.

3.1. הגדר מסלול להתנתקות

ראשית, בואו נוסיף מסלול נוסף לפרוקסי ב- שלנו application.yml:

zuul: מסלולים: // ... auth / refresh / revoke: path: / auth / refresh / revoke / ** sensitive כותרות: url: // localhost: 8083 / auth / realms / baeldung / protocol / openid-connect / logout / / אימות / רענון מסלול

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

הוספנו מסלול משנה במקום מסלול ראשי על מנת לקבל גישה ל- HTTP בלבד refreshToken קובץ cookie, שהוגדר כדרך מוגבלת מאוד / אימות / רענון (ותתי הנתיבים שלה). נראה מדוע אנו זקוקים לעוגיה בחלק הבא.

3.2. הודעה לשרת הרשאות /להתנתק

עכשיו בואו נשפר את CustomPreZuulFilter יישום כדי ליירט את / לאמת / לרענן / לבטל כתובת אתר והוסף את המידע הדרוש שיועבר לשרת ההרשאה.

פרמטרי הטופס הנדרשים להתנתקות דומים לאלה של בקשת Refresh Token, אלא שאין סוג_מענק:

מחלקה ציבורית @Component CustomPostZuulFilter מרחיב את ZuulFilter {// ... @Override public object run () {// ... if (requestURI.contains ("auth / refresh / revoke")) {String cookieValue = extractCookie (req, " refreshToken "); מחרוזת formParams = String.format ("client_id =% s & client_secret =% s & refresh_token =% s", CLIENT_ID, CLIENT_SECRET, cookieValue); בתים = formParams.getBytes ("UTF-8"); } // ...}}

הנה, פשוט חילצנו את refreshToken עוגיה ונשלח הנדרש formParams.

3.3. הסר את אסימון הרענון

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

עם זאת, במקרה זה, http בלבד קובץ cookie יישאר מוגדר על הלקוח. בהתחשב בכך שאיננו יכולים להסיר אותו באמצעות JavaScript, עלינו להסיר אותו מצד השרת.

לשם כך, בואו להוסיף ל CustomPostZuulFilter יישום המיירט את / לאמת / לרענן / לבטל כתובת אתר כך שתהיה הסר את refreshToken עוגייה כשנתקלים בכתובת אתר זו:

מחלקה ציבורית @Component CustomPostZuulFilter מרחיב את ZuulFilter {// ... @Override public object run () {// ... מחרוזת requestMethod = ctx.getRequest (). GetMethod (); if (requestURI.contains ("auth / refresh / revoke")) {Cookie cookie = cookie new ("refreshToken", ""); cookie.setMaxAge (0); ctx.getResponse (). addCookie (cookie); } // ...}}

3.4. הסר את אסימון הגישה מהלקוח Angular

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

בואו נוסיף שיטה לבקר Angular שלנו שמנקה את ה- אסימון גישה עוגיה וקוראת ל / לאמת / לרענן / לבטל מיפוי פוסט:

יציאה () {let headers = new HttpHeaders ({'Content-type': 'application / x-www-form-urlencoded; charset = utf-8'}); this._http.post ('אימות / רענון / ביטול', {}, {כותרות: כותרות}). עשה מנוי (data => {Cookie.delete ('access_token'); window.location.href = '// localhost: 8089 / ';}, err => התראה (' לא ניתן היה להתנתק ')); }

פונקציה זו תיקרא בעת לחיצה על כפתור התנתקות:

להתנתק

4. מסקנה

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

קוד המקור המלא של הדוגמאות ניתן למצוא באתר GitHub.


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