נקודות כניסה מרובות באבטחת אביב

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

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

זה כרוך בעיקר בהגדרת מספר רב http חוסם בקובץ תצורה של XML או במספר רב HttpSecurity מקרים על ידי הרחבת ה- מתאם WebSecurityConfigurer כיתה מספר פעמים.

2. תלות Maven

לצורך פיתוח נצטרך התלות הבאה:

 org.springframework.boot spring-boot-starter-security 2.2.2.RELEASE org.springframework.boot spring-boot-starter-web 2.2.2.RELEASE org.springframework.boot spring-boot-starter-thymeleaf 2.2.2. RELEASE org.springframework.boot spring-boot-starter-test 2.2.2.RELEASE org.springframework.security אביב-אבטחה-מבחן 5.2.2.RELEASE 

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

3. נקודות כניסה מרובות

3.1. נקודות כניסה מרובות עם רכיבי HTTP מרובים

בואו נגדיר את מחלקת התצורה הראשית שתחזיק מקור משתמש:

@Configuration @EnableWebSecurity מחלקה ציבורית MultipleEntryPointsSecurityConfig {@Bean Public UserDetailsService userDetailsService () זורק חריג {InMemoryUserDetailsManager manager = InMemoryUserDetailsManager חדש (); manager.createUser (משתמש .withUsername ("משתמש"). סיסמה (מקודד (). קידוד ("userPass")) .roles ("USER"). build ()); manager.createUser (משתמש .withUsername ("admin"). סיסמה (מקודד (). קידוד ("adminPass")) .roles ("ADMIN"). build ()); מנהל החזר; } @Bean מקודד PasswordEncoder () להחזיר BCryptPasswordEncoder חדש (); }}

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

אנו נשתמש כאן בדוגמה המונעת על ידי אימות בסיסי, ונשתמש טוב בעובדה ש Spring Security תומך בהגדרה של רכיבי HTTP מרובים בתצורות שלנו.

בעת שימוש בתצורת Java, הדרך להגדיר תחומי אבטחה מרובים היא להיות מרובים @תְצוּרָה שיעורים המרחיבים את מתאם WebSecurityConfigurer מחלקת בסיס - לכל אחת תצורת אבטחה משלה. שיעורים אלה יכולים להיות סטטיים ולהציב אותם בתוך התצורה הראשית.

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

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

  • אחד למשתמשים מנהליים המשתמשים באימות בסיסי של HTTP
  • אחד למשתמשים רגילים המשתמשים באימות טפסים
  • ואחד למשתמשים אורחים שאינם דורשים אימות

נקודת הכניסה שהוגדרה עבור משתמשים אדמיניסטרטיביים מאבטחת כתובות אתרים של הטופס / מנהל / ** לאפשר רק למשתמשים בעלי תפקיד ADMIN ודורש אימות HTTP בסיסי עם נקודת כניסה מסוג בסיסי אימות כניסה שמוגדר באמצעות authenticationEntryPoint () שיטה:

@Configuration @Order (1) מחלקה סטטית ציבורית App1ConfigurationAdapter מרחיב את WebSecurityConfigurerAdapter {@Override מוגן חלל להגדיר (HttpSecurity http) זורק חריג {http.antMatcher ("/ admin / **"). AutorizeRequests (). AnyRequest (). HasRole (" ADMIN "). ו- (). HttpBasic (). AuthenticationEntryPoint (authenticationEntryPoint ()); } @Bean AuthenticationEntryPoint authenticationEntryPoint () {BasicAuthenticationEntryPoint entryPoint = BasicAuthenticationEntryPoint חדש (); entryPoint.setRealmName ("תחום מנהל"); החזר כניסהPoint; }}

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

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

3.2. נקודות כניסה מרובות, אותו אלמנט HTTP

לאחר מכן, בואו נגדיר את התצורה של כתובות אתרים של הטופס /מִשׁתַמֵשׁ/** אליהם משתמשים רגילים בעלי תפקיד USER יכולים לגשת באמצעות אימות טופס:

@Configuration @Order (2) מחלקה סטטית ציבורית App2ConfigurationAdapter מרחיב את WebSecurityConfigurerAdapter {configure void configure (HttpSecurity http) זורק חריג {http.antMatcher ("/ user / **"). AuthorizeRequests (). AnyRequest (). HasRole ("משתמש" ) .and () // formLogin תצורה .and () .exceptionHandling () .defaultAuthenticationEntryPointFor (loginUrlauthenticationEntryPointWithWarning (), AntPathRequestMatcher חדש ("/ user / private / **")) .defaultAuthenticationEntryPointFor (loginUrth משתמש / כללי / ** ")); }}

כפי שאנו רואים, דרך נוספת להגדרת נקודות כניסה, מלבד שיטת authenticationEntryPoint (), היא להשתמש defaultAuthenticationEntryPointFor () שיטה. זה יכול להגדיר מספר נקודות כניסה שתואמות תנאים שונים בהתבסס על a RequestMatcher לְהִתְנַגֵד.

ה RequestMatcher הממשק כולל יישומים המבוססים על סוגים שונים של תנאים, כגון נתיב התאמה, סוג מדיה או regexp. בדוגמה שלנו, השתמשנו ב- AntPathRequestMatch כדי להגדיר שתי נקודות כניסה שונות לכתובות אתרים של הטפסים / משתמש / פרטי / ** ו / משתמש / כללי / **.

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

@Bean AuthenticationEntryPoint publicUrlauthenticationEntryPoint () {להחזיר LoginUrlAuthenticationEntryPoint חדש ("/ userLogin"); } @Bean AuthenticationEntryPoint loginUrlauthenticationEntryPointWithWarning () {להחזיר LoginUrlAuthenticationEntryPoint חדש ("/ userLoginWithWarning"); }

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

במקרה זה, נקודות הכניסה הן מסוגן LoginUrlAuthenticationEntryPointוהשתמש בכתובת URL שונה של דף הכניסה: /כניסת משתמש לדף כניסה פשוט ו / userLoginWithWarning לדף כניסה המציג גם אזהרה בעת ניסיון לגשת ל- /מִשׁתַמֵשׁ/ כתובות אתרים פרטיות.

תצורה זו תדרוש גם הגדרת ה- /כניסת משתמש ו / userLoginWithWarning מיפויי MVC ושני עמודים עם טופס כניסה רגיל.

לצורך אימות הטופס, חשוב מאוד לזכור כי כל כתובת אתר הדרושה לתצורה, כגון כתובת ה- URL לעיבוד הכניסה, צריכה לעקוב אחר /מִשׁתַמֵשׁ/** פורמט או להיות מוגדר אחרת להיות נגיש.

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

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

3.3. אלמנט HTTP חדש, ללא נקודת כניסה

לבסוף, בואו נגדיר את התצורה השלישית עבור כתובות אתרים של הטופס /אוֹרֵחַ/** שיאפשר לכל סוגי המשתמשים, כולל משתמשים לא מאומתים:

@Configuration @Order (3) מחלקה סטטית ציבורית App3ConfigurationAdapter מרחיב את WebSecurityConfigurerAdapter {configure void configure (HttpSecurity http) זורק חריג {http.antMatcher ("/ guest / **"). AuthorizeRequests (). AnyRequest (). PermitAll (); }}

3.4. תצורת XML

בואו נסתכל על תצורת ה- XML ​​המקבילה לשלושה HttpSecurity מקרים בסעיף הקודם.

כצפוי, זה יכיל שלושה XML נפרדים חסימות.

בשביל ה / מנהל / ** כתובות אתרים שתצורת ה- XML ​​תשתמש בהן נקודת כניסה- ref תכונה של http-basic אֵלֵמֶנט:

יש לציין כי אם משתמשים בתצורת XML, התפקידים צריכים להיות בצורה תַפְקִיד_.

התצורה עבור /מִשׁתַמֵשׁ/** כתובות אתרים יצטרכו להתפרק לשניים http חסימות ב- xml מכיוון שאין מקבילה ישירה ל- defaultAuthenticationEntryPointFor () שיטה.

התצורה של כתובות URL / משתמש / כללי / ** היא:

  // תצורת התחברות טופס 

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

  // תצורת התחברות טופס 

בשביל ה /אוֹרֵחַ/** כתובות אתרים שיהיו לנו http אֵלֵמֶנט:

חשוב גם כאן שלפחות XML אחד החסימה חייבת להתאים לתבנית / **.

4. גישה לכתובות אתרים מוגנות

4.1. תצורת MVC

בואו ליצור מיפוי בקשות התואם לדפוסי ה- URL שאבטחנו:

@Controller מחלקה ציבורית PagesController {@GetMapping ("/ admin / myAdminPage") ציבורי מחרוזת getAdminPage () {להחזיר "multipleHttpElems / myAdminPage"; } @GetMapping ("/ user / general / myUserPage") מחרוזת ציבורית getUserPage () {להחזיר "multipleHttpElems / myUserPage"; } @GetMapping ("/ user / private / myPrivateUserPage") מחרוזת ציבורית getPrivateUserPage () {להחזיר "multipleHttpElems / myPrivateUserPage"; } @GetMapping ("/ guest / myGuestPage") מחרוזת ציבורית getGuestPage () {להחזיר "multipleHttpElems / myGuestPage"; } @ GetMapping ("/ multipleHttpLinks") מחרוזת ציבורית getMultipleHttpLinksPage () {return "multipleHttpElems / multipleHttpLinks"; }}

ה / multipleHttpLinks מיפוי יחזיר דף HTML פשוט עם קישורים לכתובות האתר המוגנות:

דף מנהל דף משתמש דף דף משתמש פרטי דף אורח

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

ברוך הבא מנהל! חזרה לקישורים

4.2. אתחול היישום

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

@SpringBootApplication מחלקה ציבורית MultipleEntryPointsApplication {public static void main (String [] args) {SpringApplication.run (MultipleEntryPointsApplication.class, args); }}

אם אנו רוצים להשתמש בתצורת ה- XML, עלינו להוסיף גם את ה- @ImportResource ({"classpath *: spring-security-multiple-entry.xml"}) ביאור למעמד הראשי שלנו.

4.3. בדיקת תצורת האבטחה

בואו נקבע מחלקת בדיקות JUnit בה נוכל להשתמש כדי לבדוק את כתובות ה- URL המוגנות שלנו:

@RunWith (SpringRunner.class) @WebAppConfiguration @SpringBootTest (מחלקות = MultipleEntryPointsApplication.class) מחלקה ציבורית MultipleEntryPointsTest {@Autowired פרטי WebApplicationContext wac; @Autowired פרטיChainProxy springSecurityFilterChain; פרטי MockMvc mockMvc; @ לפני התקנת הריק הציבורי () {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac) .addFilter (springSecurityFilterChain) .build (); }}

לאחר מכן, בואו נבדוק את כתובות האתרים באמצעות ה- מנהל מִשׁתַמֵשׁ.

כאשר מבקשים את / admin / adminPage כתובת אתר ללא אימות בסיסי של HTTP, עלינו לצפות לקבל קוד סטטוס לא מורשה, ולאחר הוספת האימות קוד הסטטוס צריך להיות בסדר 200.

אם מנסים לגשת אל / user / userPage כתובת אתר עם משתמש הניהול, עלינו לקבל סטטוס 302 אסור:

@Test ציבורי בטל כאשר TestAdminCredentials_thenOk () זורק חריג {mockMvc.perform (get ("/ admin / myAdminPage")). AndExpect (status (). IsUnauthorized ()); mockMvc.perform (get ("/ admin / myAdminPage") .with (httpBasic ("admin", "adminPass"))). andExpect (status (). isOk ()); mockMvc.perform (get ("/ user / myUserPage") .with (user ("admin"). סיסמה ("adminPass"). תפקידים ("ADMIN"))). andExpect (status (). isForbidden ()); }

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

@Test ציבורי בטל כאשר TestUserCredentials_thenOk () זורק חריג {mockMvc.perform (get ("/ user / general / myUserPage")). AndExpect (status (). IsFound ()); mockMvc.perform (get ("/ user / general / myUserPage"). with (user ("user"). password ("userPass"). role ("USER"))). andExpect (status (). isOk () ); mockMvc.perform (get ("/ admin / myAdminPage"). with (user ("user"). password ("userPass"). role ("USER"))). andExpect (status (). isForbidden ()); }

במבחן השני אנו יכולים לראות שחסר את אימות הטופס יביא למצב של 302 נמצא במקום לא מורשה, מכיוון ש- Spring Security ינתב לטופס הכניסה.

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

@Test ציבורי בטל givenAnyUser_whenGetGuestPage_thenOk () זורק חריג {mockMvc.perform (get ("/ guest / myGuestPage")). AndExpect (status (). IsOk ()); mockMvc.perform (get ("/ guest / myGuestPage"). with (user ("user"). password ("userPass"). role ("USER"))). andExpect (status (). isOk ()); mockMvc.perform (get ("/ guest / myGuestPage") .with (httpBasic ("admin", "adminPass"))). andExpect (status (). isOk ()); }

5. מסקנה

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

קוד המקור המלא של הדוגמאות ניתן למצוא באתר GitHub. כדי להפעיל את היישום, בטל את התגובה MultipleEntryPointsApplicationשיעור התחלה התג ב- pom.xml והפעל את הפקודה קפיץ אתחול mvn: לרוץואז ניגש אל / multipleHttpLinks כתובת אתר.

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

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

mvn נקי להתקין -PentryPoints


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