Spring Security 5 - כניסה ל- OAuth2

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

אביב ביטחון 5 מציג חדש OAuth2LoginConfigurer בכיתה בה אנו יכולים להשתמש לצורך קביעת תצורה של שרת הרשאות חיצוני.

במאמר זה, נחקור כמה מאפשרויות התצורה השונות הזמינות עבור oauth2Login () אֵלֵמֶנט.

2. תלות Maven

בפרויקט Spring Boot, כל מה שאנחנו צריכים זה להוסיף את המתנע spring-boot-starter-oauth2-client:

 org.springframework.boot spring-boot-starter-oauth2-client 2.3.3.RELEASE 

בפרויקט שאינו אתחול, בנוסף לתלות האביב והאביב הרגילה, נצטרך להוסיף במפורש את ה- אביב-אבטחה-oauth2-client ו אביב-ביטחון-oauth2-jose תלות:

 org.springframework.security spring-security-oauth2-client 5.3.4.RELEASE org.springframework.security spring-security-oauth2-jose 5.3.4.RELEASE 

3. הגדרת לקוחות

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

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

3.1. השגת אישורי לקוח

כדי להשיג אישורי לקוח לאימות Google OAuth2, עבור אל מסוף ה- API של Google - סעיף "אישורים".

כאן ניצור אישורים מסוג "מזהה לקוח OAuth2" עבור יישום האינטרנט שלנו. התוצאה היא ש- Google מגדירה עבורנו מזהה לקוח וסוד.

עלינו גם להגדיר URI מנותב להפניה מחדש במסוף Google, שהוא הנתיב אליו יופנו המשתמשים לאחר שהם נכנסים בהצלחה ל- Google.

כברירת מחדל, Spring Boot מגדיר את ה- URI להפניה מחדש כ- / login / oauth2 / code / {registrationId}. לכן, עבור Google נוסיף את ה- URI:

// localhost: 8081 / login / oauth2 / code / google

כדי להשיג את אישורי הלקוח לאימות בפייסבוק, עלינו לרשום יישום באתר פייסבוק למפתחים ולהגדיר את ה- URI המתאים כ- URI תקף של OAuth להפניה מחדש:

// localhost: 8081 / login / oauth2 / code / facebook

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

לאחר מכן, עלינו להוסיף את אישורי הלקוח ל- application.properties קוֹבֶץ. מאפייני Spring Security מוקדמים עם "Spring.security.oauth2.client.registration" ואחריו שם הלקוח ואז שם נכס הלקוח:

spring.security.oauth2.client.registration.google.client-id = spring.security.oauth2.client.registration.google.client-secret = spring.security.oauth2.client.registration.facebook.client-id = spring. security.oauth2.client.registration.facebook.client-secret =

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

תצורת אבטחת האינטרנט האוטומטית שווה ערך להגדרה פשוטה oauth2Login () אֵלֵמֶנט:

@Configuration מחלקה ציבורית SecurityConfig מרחיב את WebSecurityConfigurerAdapter {@Override מוגן ריק להגדיר (HttpSecurity http) זורק חריג {http.authorizeRequests () .anyRequest (). מאומת () .and () .oauth2Login (); }}

כאן נוכל לראות את oauth2Login () אלמנט משמש באופן דומה לזה שהיה ידוע כבר httpBasic () ו formLogin () אלמנטים.

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

3.4. לקוחות אחרים

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

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

4. התקנה בפרויקט שאינו אתחול

4.1. ליצור ClientRegistrationRepository אפונה

אם איננו עובדים עם יישום Spring Boot, נצטרך להגדיר א ClientRegistrationRepository אפונה המכיל ייצוג פנימי של פרטי הלקוח שבבעלות שרת ההרשאה:

@Configuration @EnableWebSecurity @PropertySource ("classpath: application.properties") מחלקה ציבורית SecurityConfig מרחיב את WebSecurityConfigurerAdapter {client private List List clients = Arrays.asList ("google", "facebook"); @Bean ClientRegistrationRepository clientRegistrationRepository () {רישום רישומים = clients.stream () .מפה (c -> getRegistration (c)). פילטר (רישום -> רישום! = Null) .collect (Collectors.toList ()); להחזיר InMemoryClientRegistrationRepository חדש (רישומים); }}

כאן אנו יוצרים InMemoryClientRegistrationRepository עם רשימה של רישום לקוח חפצים.

4.2. בִּניָן רישום לקוח חפצים

בוא נראה את getRegistration () שיטה הבונה אובייקטים אלה:

מחרוזת סטטית פרטית CLIENT_PROPERTY_KEY = "spring.security.oauth2.client.registration."; @ סביבה פרטית אוטומטית מאושרת; פרטי ClientRegistration getRegistration (לקוח מחרוזת) {מחרוזת clientId = env.getProperty (CLIENT_PROPERTY_KEY + לקוח + ".client-id"); אם (clientId == null) {return null; } מחרוזת clientSecret = env.getProperty (CLIENT_PROPERTY_KEY + client + ".client-secret"); אם (client.equals ("google")) {return CommonOAuth2Provider.GOOGLE.getBuilder (client) .clientId (clientId) .clientSecret (clientSecret) .build (); } אם (client.equals ("facebook")) {return CommonOAuth2Provider.FACEBOOK.getBuilder (client) .clientId (clientId) .clientSecret (clientSecret) .build (); } להחזיר אפס; }

כאן אנו קוראים את אישורי הלקוח מדומה application.properties קובץ ולאחר מכן באמצעות CommonOauth2Provider enum שכבר הוגדר ב- Spring Security עבור שאר נכסי הלקוחות עבור לקוחות גוגל ופייסבוק.

כל אחד רישום לקוח מופע תואם לקוח.

4.3. רישום ClientRegistrationRepository

לבסוף, עלינו ליצור OAuth2AuthorizedClientService שעועית על בסיס ClientRegistrationRepository שעועית ולרשום את שניהם עם oauth2Login () אֵלֵמֶנט:

התצורה הריקה מוגנת @Override (HttpSecurity http) זורקת חריגה {http.authorizeRequests (). AnyRequest (). מאומת () .and () .oauth2Login () .clientRegistrationRepository (clientRegistrationRepository ()) .authorizedClientService (שירות clientised); } @Bean ציבורי OAuth2AuthorizedClientService מורשהClientService () {החזר InMemoryOAuth2AuthorizedClientService חדש (clientRegistrationRepository ()); }

כפי שמעידים כאן, אנחנו יכולים להשתמש ב- clientRegistrationRepository () שיטה של oauth2Login () כדי לרשום מאגר רישום מותאם אישית.

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

בואו נמשיך בהתאמה אישית נוספת של תהליך הכניסה שלנו.

5. התאמה אישית oauth2Login ()

ישנם מספר אלמנטים בהם משתמשים בתהליך OAuth 2 ושניתן להתאים אישית באמצעותם oauth2Login () שיטות.

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

בואו נראה כיצד נוכל להתאים אישית את אלה בתצורה שלנו.

5.1. דף כניסה מותאם אישית

למרות ש- Spring Boot מייצר עבורנו דף כניסה ברירת מחדל, בדרך כלל נרצה להגדיר דף מותאם אישית משלנו.

נתחיל בתצורה של כתובת כניסה חדשה עבור ה- oauth2Login () אלמנט באמצעותloginPage () שיטה:

התצורה הריקה המוגנת על ידי @Override (HttpSecurity http) זורקת חריג {http.authorizeRequests () .antMatchers ("/ oauth_login") .permitAll () .anyRequest () .authenticated () .and () .oauth2Login () .loginPage ("/ oauth_login "); }

הנה, הגדרנו את כתובת ה- URL שלנו לכניסה / oauth_login.

לאחר מכן, בואו נגדיר א LoginController בשיטה הממפה לכתובת אתר זו:

@Controller מחלקה ציבורית LoginController {private static String autorisationRequestBaseUri = "oauth2 / authorization"; מפה oauth2AuthenticationUrls = HashMap חדש (); @ ClientRegistrationRepository ClientRegistrationRepository פרטי; @GetMapping ("/ oauth_login") מחרוזת ציבורית getLoginPage (מודל מודל) {// ... להחזיר "oauth_login"; }}

בשיטה זו יש לשלוח לתצוגה מפה של הלקוחות הזמינים ונקודות הקצה של ההרשאה שלהם, שנשיג מה- ClientRegistrationRepository אפונה:

מחרוזת ציבורית getLoginPage (מודל מודל) {Iterable clientRegistrations = null; סוג ResolvableType = ResolvableType.forInstance (clientRegistrationRepository) .as (Iterable.class); if (type! = ResolvableType.NONE && ClientRegistration.class.isAssignableFrom (type.resolveGenerics () [0])) {clientRegistrations = (Iterable) clientRegistrationRepository; } clientRegistrations.forEach (registration -> oauth2AuthenticationUrls.put (registration.getClientName (), authorisationRequestBaseUri + "/" + registry.getRegistrationId ())); model.addAttribute ("urls", oauth2AuthenticationUrls); החזר "oauth_login"; }

לבסוף, עלינו להגדיר את שלנו oauth_login.html עמוד:

התחבר באמצעות:

לָקוּחַ

זהו דף HTML פשוט המציג קישורים לאימות עם כל לקוח.

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

5.2. אימות מותאם אישית הצלחה והתנהגות כישלון

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

  • defaultSuccessUrl () ו failureUrl () - להפניית המשתמש לכתובת אתר נתונה
  • successHandler () ו failHandler () - לביצוע לוגיקה מותאמת אישית בעקבות תהליך האימות

בואו נראה כיצד נוכל להגדיר כתובות אתרים מותאמות אישית להפניית המשתמש ל:

.oauth2Login () .defaultSuccessUrl ("/ loginSuccess") .failureUrl ("/ loginFailure");

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

אם אנו רוצים שהמשתמש יישלח תמיד אל ה- / loginSuccess כתובת אתר, ללא קשר אם הייתה בדף מאובטח לפני כן או לא, אנו יכולים להשתמש בשיטה defaultSuccessUrl ("/ loginSuccess", נכון).

כדי להשתמש במטפל מותאם אישית, נצטרך ליצור מחלקה שמיישמת את ה- AuthenticationSuccessHandler אוֹ AuthenticationFailureHandler ממשקים, לעקוף את השיטות שעברו בירושה, ואז להגדיר את השעועית באמצעות successHandler () ושיטות כישלון Handler ().

5.3. נקודת סיום הרשאה מותאמת אישית

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

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

.oauth2Login () .authorizationEndpoint () .baseUri ("/ oauth2 / authorize-client") .authorizationRequestRepository (authorisquestRepository ());

הנה, שינינו את ה- baseUri ל / oauth2 / authorize-client במקום ברירת המחדל / oauth2 / הרשאה. אנו גם מגדירים במפורש authorization RequestRepository () שעועית שעלינו להגדיר:

@Bean AuthorizationRequestRepository authorisationRequestRepository () {להחזיר HttpSessionOAuth2AuthorizationRequestRepository חדש (); }

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

5.4. נקודת סיום אסימון מותאמת אישית

האסימון נקודת סיום מעבד אסימוני גישה.

בואו נגדיר במפורש את tokenEndpoint ()עם יישום לקוח התגובה המוגדר כברירת מחדל:

.oauth2Login () .tokenEndpoint () .accessTokenResponseClient (accessTokenResponseClient ());

והנה שעועית לקוח התגובה:

@Bean ציבורי OAuth2AccessTokenResponseClient accessTokenResponseClient () {להחזיר NimbusAuthorizationCodeTokenResponseClient חדש (); }

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

כמובן שנוכל להחליף לקוח תגובה מותאם אישית.

5.5. נקודת סיום להפניה מחדש בהתאמה אישית

זו נקודת הקצה להפניה אליה לאחר אימות עם הספק החיצוני.

בואו נראה כיצד נוכל לשנות את baseUri לנקודת הסיום להפניה:

.oauth2Login () .redirectionEndpoint () .baseUri ("/ oauth2 / redirect")

ברירת המחדל של ה- URI היא התחברות / oauth2 / קוד.

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

5.6. נקודת סיום של מידע מותאם אישית למשתמש

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

אנו יכולים להתאים אישית נקודת קצה זו באמצעות ה- userInfoEndpoint () שיטה. לשם כך אנו יכולים להשתמש בשיטות כגון userService () ו customUserType () כדי לשנות את אופן השגת המידע על המשתמש.

6. גישה למידע המשתמשים

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

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

@Autowired פרטי OAuth2AuthorizedClientService מורשהClientService; @GetMapping ("/ loginSuccess") מחרוזת ציבורית getLoginInfo (מודל מודל, אימות OAuth2AuthenticationToken) {לקוח OAuth2AuthorizedClient = authorClientService .loadAuthorizedClient (authentication.getAuthorizedClientRegistrationId (), authentication.getName ()); // ... להחזיר "loginSuccess"; }

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

מחרוזת userInfoEndpointUri = client.getClientRegistration () .getProviderDetails (). GetUserInfoEndpoint (). GetUri (); אם (! StringUtils.isEmpty (userInfoEndpointUri)) {RestTemplate restTemplate = RestTemplate חדש (); כותרות HttpHeaders = HttpHeaders חדשות (); headers.add (HttpHeaders.AUTHORIZATION, "נושא" + client.getAccessToken () .getTokenValue ()); HttpEntity ישות = HttpEntity חדש ("", כותרות); ResponseEntity response = restTemplate .exchange (userInfoEndpointUri, HttpMethod.GET, entity, Map.class); מפה userAttributes = response.getBody (); model.addAttribute ("שם", userAttributes.get ("שם")); }

על ידי הוספת ה- שֵׁם נכס כ דֶגֶם תכונה, אנו יכולים להציג אותה ב- loginSuccess להציג כהודעת קבלת פנים למשתמש:

חוץ מה שֵׁם, ה מפת משתמש תכונות מכיל גם מאפיינים כגון דוא"ל, שם משפחה,תמונה, מקום.

7. מסקנה

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

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


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