כניסה יחידה פשוטה עם OAuth2 באבטחת אביב

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

במדריך זה נדון כיצד ליישם SSO - כניסה יחידה - באמצעות Spring Security OAuth ו- Spring Boot, באמצעות Keycloak כשרת ההרשאות.

נשתמש בארבע יישומים נפרדים:

  • שרת Authorization - שהוא מנגנון האימות המרכזי
  • שרת משאבים - הספק של פוס
  • שתי יישומי לקוח - היישומים המשתמשים ב- SSO

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

אנחנו הולכים להשתמש ב- קוד אימות הענק סוג מ- OAuth2 כדי להניע את משלחת האימות.

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

לפי מדריך ההגירה:

Spring Security מתייחס לתכונה זו ככניסה OAuth 2.0 ואילו Spring Security OAuth מתייחס אליה כאל SSO

בסדר, בוא נקפוץ ישר פנימה.

2. שרת ההרשאה

בעבר, ערימת ה- OAuth של Spring Security הציעה אפשרות להגדיר שרת הרשאות כ- Spring Application.

עם זאת, מחסנית ה- OAuth הוצאה משימוש על ידי אביב ועכשיו נשתמש ב- Keycloak כשרת ההרשאה שלנו.

אז הפעם, נגדיר את שרת ההרשאה שלנו כשרת Keycloak מוטבע באפליקציית Spring Boot.

בתצורה המוקדמת שלנו, נגדיר שני לקוחות, ssoClient-1 ו ssoClient-2, אחד לכל יישום לקוח.

3. שרת המשאבים

לאחר מכן אנו זקוקים לשרת משאבים או ל- REST API שיספק לנו את ה- פוs אפליקציית הלקוחות שלנו תצרוך.

זה למעשה זהה לזה שהשתמשנו בו בעבר עבור אפליקציות הלקוח הזוויתי שלנו.

4. יישומי הלקוח

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

זכור זאת נצטרך שיהיו שני כאלה כדי להדגים פונקציונליות של כניסה יחידה.

4.1. תלות Maven

ראשית, נצטרך את התלות הבאות שלנו pom.xml:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-oauth2-client org.springframework.boot spring-boot-starter-thymeleaf org.thymeleaf.extras thymeleaf-extras-springsecurity5 org. מסגרת קפיצית אביב-שטף אינטרנט io.projectreactor.netty reactor-netty 

כדי לכלול את כל התמיכה בלקוח שנצטרך, כולל אבטחה, אנחנו רק צריכים להוסיף spring-boot-starter-oauth2-client. כמו כן, מאז הישן RestTemplate הולכים להיפטר, נשתמש WebClient, ובגלל זה הוספנו אביב-שטף אינטרנט ו כור-נט.

4.2. תצורת אבטחה

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

המחלקה הציבורית @EnableWebSecurity UiSecurityConfig מרחיב את WebSecurityConfigurerAdapter {@Override public void configure (HttpSecurity http) זורק חריג {http.antMatcher ("/ **") .authorizeRequests () .antMatchers ("/") .permitAest () .any. מאומת () .and () .oauth2Login (); } @Bean WebClient webClient (ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository) {ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = ServletOAuth2AuthorizedClientExchangeFilterFunter; oauth2.setDefaultOAuth2AuthorizedClient (נכון); להחזיר את WebClient.builder (). להחיל (oauth2.oauth2Configuration ()). build (); }}

החלק המרכזי בתצורה זו הוא oauth2Login () שיטה, המשמשת לאפשר תמיכה בכניסה של OAuth 2.0 של Spring Security. מכיוון שאנו משתמשים ב- Keycloak, המהווה כברירת מחדל פתרון כניסה יחיד לאפליקציות אינטרנט ושירותי אינטרנט RESTful, איננו צריכים להוסיף שום תצורה נוספת עבור SSO.

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

והנה application.yml:

קפיץ: אבטחה: oauth2: לקוח: רישום: מותאם אישית: לקוח מזהה: ssoClient-1 סוד לקוח: ssoClientSecret-1 היקף: לקרוא, לכתוב הרשאה-מענק סוג: הרשאה_קודה להפנות מחדש-אורי: // localhost: 8082 / ui- one / login / oauth2 / code / custom custom: custom: authorisation-uri: // localhost: 8083 / auth / realms / baeldung / protocol / openid-connect / auth token-uri: // localhost: 8083 / auth / realms / baeldung / פרוטוקול / openid-connect / token user-info-uri: // localhost: 8083 / auth / realms / baeldung / protocol / openid-connect / userinfo user-name-attribute: preferred_username thymeleaf: cache: false server: port: 8082 servlet: path-path: / ui-one resourceserver: api: project: url: // localhost: 8081 / sso-resource-server / api / foos / 

פה, spring.security.oauth2.client.registration הוא מרחב השמות הבסיסי לרישום לקוח. הגדרנו לקוח עם מזהה רישום המותאם אישית. ואז הגדרנו את זה מזהה לקוח, סוד לקוח, תְחוּם, סוג מענק הרשאה ו redirect-uri, שכמובן, צריך להיות זהה לזה שהוגדר עבור שרת ההרשאה שלנו.

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

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

4.3. הבקר

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

@Controller מחלקה ציבורית FooClientController {@Value ("$ {resourceserver.api.url}") מחרוזת פרטית fooApiUrl; @Client webClient פרטי מאושר; @GetMapping ("/ foos") מחרוזת ציבורית getFoos (דגם מודל) {רשימה foos = this.webClient.get () .uri (fooApiUrl). Retrieve () .bodyToMono (ParameterizedTypeReference חדש() {}) .block (); model.addAttribute ("foos", foos); להחזיר "foos"; }}

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

4.4. חזיתי

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

ליישום הלקוחות שלנו כאן יש חזית פשוטה מאוד; הנה ה index.html:

אביב OAuth לקוח אביב - Thymeleaf - ברוך הבא!

התחברות

וה foos.html:

לקוח OAuth של אביב Thymeleaf -1 היי, שם משתמש מועדף 
תְעוּדַת זֶהוּתשֵׁם
אין שוטים
תְעוּדַת זֶהוּת שֵׁם

ה foos.html הדף צריך לאמת את המשתמשים. אם משתמש שאינו מאומת מנסה לגשת foos.html, הם יופנו לדף הכניסה של קייקלואק תחילה.

4.5. יישום הלקוח השני

נגדיר יישום שני, אביב OAuth לקוח Thymeleaf -2 באמצעות אחר client_idssoClient-2.

זה בעיקר יהיה זהה ליישום הראשון שתיארנו זה עתה.

ה application.yml יהיה שונה כדי לכלול שונה client_id, סוד לקוח ו redirect_uri ב spring.security.oauth2.client.registration:

קפיץ: אבטחה: oauth2: לקוח: רישום: מותאם אישית: לקוח-מזהה: ssoClient-2 סוד לקוח: ssoClientSecret-2 היקף: לקרוא, לכתוב הרשאה-מענק-סוג: הרשאת קוד להפנות מחדש-אורי: // localhost: 8084 / ui- שניים / login / oauth2 / code / custom

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

שרת: יציאה: 8084 servlet: path-path: / ui-two

לבסוף, נשנה את ה- HTML הקידומי כדי שיהיה להם כותרת אביב OAuth לקוח Thymeleaf - 2 במקום – 1 כדי שנוכל להבחין בין השניים.

5. בדיקת התנהגות SSO

כדי לבדוק התנהגות SSO, בוא נפעיל את היישומים שלנו.

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

עכשיו בואו נפתח דפדפן, נגיד Chrome ונכנס אליו לקוח -1 באמצעות האישורים [מוגן בדוא"ל] / 123. לאחר מכן, בחלון או בכרטיסייה אחרת, לחץ על כתובת האתר של לקוח -2. בלחיצה על כפתור הכניסה, יופנה אל ה- פוס עמוד מייד, עוקף את שלב האימות.

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

6. מסקנה

במדריך זה התמקדנו ביישום כניסה יחידה באמצעות Spring Security OAuth2 ו- Spring Boot באמצעות Keycloak כספק הזהות.

כמו תמיד, ניתן למצוא את קוד המקור המלא ב- GitHub.