אביב אבטחה - @ PreFilter ו- @ PostFilter

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

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

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

2. היכרות @לפני סינון ו @PostFilter

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

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

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

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

הערות התיזה אינן פעילות כברירת מחדל - נצטרך לאפשר אותן באמצעות ה- @EnableGlobalMethodSecurity ביאור ו prePostEnabled = נכון בתצורת האבטחה שלנו:

@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity (prePostEnabled = true) מחלקה ציבורית WebSecurityConfig מרחיב את WebSecurityConfigurerAdapter {// ...}

3. כתיבת כללי אבטחה

כדי לכתוב את כללי האבטחה בשתי ההערות הללו - נשתמש בביטויי Spring-EL; אנו יכולים גם להשתמש באובייקט המובנה filterObject כדי לקבל התייחסות לרכיב הרשימה המסוים הנבדק.

Spring Security מספק אובייקטים מובנים רבים אחרים כדי ליצור כללים מאוד ספציפיים ומדויקים.

לדוגמה, אנחנו יכולים להשתמש @לפני סינון כדי לבדוק אם נאמן רכוש של א מְשִׁימָה האובייקט שווה ל- שֵׁם של המשתמש המאומת כעת:

@PostFilter ("filterObject.assignee == authentication.name") רשימת findAll () {...}

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

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

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

@PostFilter ("hasRole ('MANAGER') או filterObject.assignee == authentication.name") רשימה findAll () {// ...}

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

עכשיו בואו נסנן רשימה שהועברה כפרמטר ל- a לשמור באמצעות שיטה @לפני סינון:

@PreFilter ("hasRole ('MANAGER') או filterObject.assignee == authentication.name") שמירה ניתנת להשמדה (ישויות ניתנות לניתנים לניתוב) {// ...}

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

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

4. ביצוע ברשימות גדולות

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

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

5. מסקנה

מאמר מהיר זה הסביר כיצד ליצור יישום פשוט, אך מאובטח, באמצעות יישומי Spring Security @לפני סינון ו @PostFilter ביאורים.

בדוק את דוגמת הקוד המלא במאגר Github זה.


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