תהליך הרישום עם אבטחת אביב

מאמר זה הוא חלק מסדרה: • מדריך רישום אבטחה באביב

• תהליך הרישום עם אבטחת אביב (מאמר נוכחי) • הרשמה - הפעל חשבון חדש בדוא"ל

• רישום אבטחה באביב - שלח שוב דוא"ל אימות

• הרשמה באבטחת אביב - קידוד סיסמאות

• ממשק ה- API לרישום הופך ל- RESTful

• אבטחת אביב - אפס את הסיסמה שלך

• רישום - חוזק סיסמא וכללים

• עדכון הסיסמה שלך

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

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

המטרה כאן היא להוסיף תהליך רישום מלא המאפשר למשתמש להירשם, מאמת ומתמיד נתוני משתמשים.

2. דף הרישום

ראשית - בואו נשתמש בדף רישום פשוט המוצג את השדות הבאים:

  • שֵׁם (שם פרטי ושם משפחה)
  • אימייל
  • סיסמה (ושדה אישור סיסמא)

הדוגמה הבאה מראה פשוט registration.html עמוד:

דוגמא 2.1.

טופס

ראשון

שגיאת אימות

אחרון

שגיאת אימות

אימייל

שגיאת אימות

סיסמה

שגיאת אימות

לאשר הגש כניסה

3.אובייקט DTO המשתמש

אנחנו צריכים אובייקט העברת נתונים כדי לשלוח את כל פרטי ההרשמה אל backend האביב שלנו. ה DTO אובייקט צריך לכלול את כל המידע שנדרש מאוחר יותר כשאנחנו יוצרים ומאכלסים את המידע שלנו מִשׁתַמֵשׁ לְהִתְנַגֵד:

מחלקה ציבורית UserDto {@NotNull @NotEmpty פרטי מחרוזת שם פרטי; @NotNull @NotEmpty שם משפחה פרטי מחרוזת; @NotNull @NotEmpty סיסמת מחרוזת פרטית; התאמת מחרוזת פרטית סיסמא; @NotNull @NotEmpty דוא"ל מחרוזת פרטי; // סטרים וקובעים סטנדרטיים}

שימו לב שהשתמשנו בתקן javax.validation ביאורים על שדות אובייקט DTO. בהמשך, אנחנו הולכים גם ליישם הערות אימות מותאמות אישית משלנו לאימות הפורמט של כתובת הדואר האלקטרוני וכן לאישור הסיסמה. (לִרְאוֹת סעיף 5)

4. בקר הרישום

א הירשם קישור ב- התחברות הדף ייקח את המשתמש אל הַרשָׁמָה עמוד. קצה אחורי זה של דף זה מתגורר בבקר הרישום וממופה אליו "/ משתמש / רישום":

דוגמה 4.1. - ה showRegistration שיטה

@GetMapping ("/ user / registration") ציבורי מחרוזת showRegistrationForm (בקשת WebRequest, מודל מודל) {UserDto userDto = UserDto חדש (); model.addAttribute ("משתמש", userDto); להחזיר "רישום"; }

כאשר הבקר מקבל את הבקשה "/ משתמש / רישום", זה יוצר את החדש UserDto אובייקט שיגבה את הַרשָׁמָה טופס, קושר אותו וחוזר - די פשוט.

5. אימות נתוני רישום

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

  1. כל השדות הנדרשים מלאים (אין שדות ריקים או ריק)
  2. כתובת הדוא"ל חוקית (מעוצבת היטב)
  3. שדה אישור הסיסמה תואם את שדה הסיסמה
  4. החשבון עדיין לא קיים

5.1. האימות המובנה

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

כדי להפעיל את תהליך האימות, פשוט נסמן את האובייקט בשכבת הבקר עם ה- @תָקֵף ביאור:

ModelAndView ציבורי registerUserAccount (@ModelAttribute ("משתמש") @Valid UserDto userDto, בקשת HttpServletRequest, שגיאות שגיאות) {...}

5.2. אימות מותאם אישית לבדיקת תוקף דוא"ל

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

דף מהיר כאן - אנו מרימים ביאור מותאם אישית משלנו במקום שינה@אימייל מכיוון ש- Hibernate שוקל את פורמט כתובות האינטרא-נט הישן: [מוגן בדוא"ל] כתקף (ראה מאמר Stackoverflow), וזה לא טוב.

להלן הערת אימות הדוא"ל והמאמת המותאם אישית:

דוגמא 5.2.1. - ההערה המותאמת אישית לאימות דוא"ל

@Target ({TYPE, FIELD, ANNOTATION_TYPE}) @Retention (RUNTIME) @Constraint (validatedBy = EmailValidator.class) @Documented public @interface ValidEmail {הודעת מחרוזת () ברירת מחדל "דוא"ל לא חוקי"; מחלקה [] קבוצות () ברירת מחדל {}; Class [] מטען מטען () ברירת מחדל {}; }

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

דוגמה 5.2.2. המנהג דוא"ל ולידאטוr:

מחלקה ציבורית EmailValidator מיישמת ConstraintValidator {דפוס תבנית פרטי; התאמה פרטית של התאמה; סופי סטטי פרטי מחרוזת EMAIL_PATTERN = "^ [_ A-Za-z0-9 - +] + (. [_ A-Za-z0-9 -] +) * @" + "[A-Za-z0-9 -] + (. [A-Za-z0-9] +) * (. [A-Za-z] {2,}) $ "; @Override חלל ציבורי מאותחל (ValidEmail constraintAnnotation) {} @Override ציבור בוליאני isValid (דוא"ל מחרוזת, ConstraintValidatorContext) {return (validateEmail (email)); } validate private booleanEmail (מייל מחרוזת) {pattern = Pattern.compile (EMAIL_PATTERN); התאמה = דפוס. התאמה (דוא"ל); התאמה חוזרת. התאמות (); }}

בואו עכשיו השתמש בהערה החדשה על שלנו UserDto יישום:

@ValidEmail @NotNull @NotEmpty דוא"ל מחרוזת פרטי;

5.3. שימוש באימות מותאם אישית לאישור סיסמה

אנו זקוקים גם להערה מותאמת אישית ולאמת כדי לוודא שה- סיסמה ו התאמת סיסמה שדות מתאימים:

דוגמא 5.3.1. - ההערה המותאמת אישית לאימות אישור סיסמא

@Target ({TYPE, ANNOTATION_TYPE}) @ Retention (RUNTIME) @Constraint (validatedBy = PasswordMatchesValidator.class) @Documented public @interface PasswordMatches {הודעת מחרוזת () ברירת מחדל "סיסמאות אינן תואמות"; מחלקה [] קבוצות () ברירת מחדל {}; Class [] מטען מטען () ברירת מחדל {}; }

שימו לב שה- @יַעַד ביאור מציין כי זהו סוּג ביאור ברמה. הסיבה לכך היא שאנחנו צריכים את כל כולו UserDto התנגד לבצע את האימות.

המאמת המותאם אישית שייקרא על ידי הערה זו מוצג להלן:

דוגמא 5.3.2. ה PasswordMatchesValidator מאמת מותאם אישית

מחלקה ציבורית PasswordMatchesValidator מיישמת ConstraintValidator {@Override Public void initialize (PasswordMatches constraintAnnotation) {} @Override boolean public isValid (Object object, ConstraintValidatorContext context) {UserDto user = (UserDto) obj; החזר user.getPassword (). שווה (user.getMatchingPassword ()); }}

עכשיו ה @PasswordMatches יש להחיל הערה על שלנו UserDto לְהִתְנַגֵד:

@PasswordMatches UserDto בכיתה ציבורית {...}

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

5.4. בדוק שהחשבון כבר לא קיים

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

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

דוגמא 5.4.1. הבקר createUserAccounשיטה מכנה את UserService Object

@PostMapping ("/ משתמש / רישום") ציבורי ModelAndView registerUserAccount (@ModelAttribute ("user") @Valid UserDto userDto, HttpServletRequest בקשה, שגיאות שגיאה) {נסה {User registered = userService.registerNewUserAccount (userDto); } לתפוס (UserAlreadyExistException uaeEx) {mav.addObject ("הודעה", "כבר קיים חשבון עבור שם המשתמש / הדוא"ל הזה."); להחזיר mav; } // שאר היישום} 

דוגמא 5.4.2. - מִשׁתַמֵשׁשֵׁרוּת בודק הודעות דוא"ל משוכפלות

המחלקה הציבורית @Service UserService מיישמת את IUserService {@ מאגר פרטי UserRepository פרטי; @Transactional @Override משתמש ציבורי registerNewUserAccount (UserDto userDto) זורק UserAlreadyExistException {if (emailExist (userDto.getEmail ())) {זרוק UserAlreadyExistException חדש ("יש חשבון עם כתובת הדוא"ל הזו:" + userDto.getEmail ()); } ... // שאר פעולות הרישום} אימייל בוליאני פרטיExist (מייל מחרוזת) {החזר userRepository.findByEmail (אימייל)! = null; }}

שירות המשתמש מסתמך על ה- UserRepository בכיתה לבדוק אם משתמש עם כתובת דוא"ל נתונה כבר קיים במסד הנתונים.

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

6. נתונים קבועים ועיבוד טפסים גימור

לסיום - בואו נשתמש בהיגיון הרישום בשכבת הבקר שלנו:

דוגמא 6.1.1. - ה RegisterAccount שיטה בבקר

@PostMapping ("/ משתמש / רישום") ציבורי ModelAndView registerUserAccount (@ModelAttribute ("user") @Valid UserDto userDto, HttpServletRequest בקשה, שגיאות שגיאה) {נסה {User registered = userService.registerNewUserAccount (userDto); } לתפוס (UserAlreadyExistException uaeEx) {mav.addObject ("הודעה", "כבר קיים חשבון עבור שם המשתמש / הדוא"ל הזה."); החזר mav; } להחזיר ModelAndView חדש ("successRegister", "user", userDto); } 

דברים שיש לשים לב אליהם בקוד לעיל:

  1. הבקר מחזיר א ModelAndView אובייקט שהוא המחלקה הנוחה לשליחת נתוני מודל (מִשׁתַמֵשׁ) קשור לנוף.
  2. הבקר יפנה לטופס ההרשמה אם נקבעו שגיאות בזמן האימות.

7.ה שירות משתמש - רשום מבצע

בוא נסיים את יישום פעולת הרישום ב- שירות משתמש:

דוגמא 7.1. ה IUserService מִמְשָׁק

ממשק ציבורי IUserService {משתמש registerNewUserAccount (UserDto userDto) זורק UserAlreadyExistException; }

דוגמא 7.2. - ה שירות משתמש מעמד

המחלקה הציבורית @Service UserService מיישמת את IUserService {@ מאגר UserRepository פרטי; @Transactional @Override משתמש ציבורי registerNewUserAccount (UserDto userDto) זורק UserAlreadyExistException {if (emailExists (userDto.getEmail ())) {זרוק UserAlreadyExistException חדש ("יש חשבון עם כתובת הדוא"ל הזו: + userDto.getEmail ());} משתמש user = משתמש חדש (); user.setFirstName (userDto.getFirstName ()); user.setLastName (userDto.getLastName ()); user.setPassword (userDto.getPassword ()); user.setEmail (userDto.getEmail ()) ; user.setRoles (Arrays.asList ("ROLE_USER")); להחזיר repository.save (user);} אימייל בוליאני פרטי Exists (דוא"ל מחרוזת) {return userRepository.findByEmail (email)! = null;}}

8. טוען פרטי משתמש לצורך כניסה לאבטחה

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

8.1. המנהג UserDetailsService

נתחיל ביישום שירות פרטי המשתמש המותאמים אישית:

@Service @Transactional public class MyUserDetailsService מיישם את UserDetailsService {@Autowired פרטי UserRepository userRepository; // פומבי UserDetails loadUserByUsername (מייל מחרוזת) זורק UsernameNotFoundException {User user = userRepository.findByEmail (email); if (user == null) {throw new UsernameNotFoundException ("לא נמצא משתמש עם שם משתמש:" + אימייל); } מופעל בוליאני = נכון; חשבון בוליאני NonExpired = true; אישורים בוליאניים NonExpired = true; חשבון בוליאני NonLocked = נכון; להחזיר org.springframework.security.core.userdetails.User (user.getEmail (), user.getPassword (). toLowerCase (), מופעל, accountNonExpired, אישורי NonExpired, accountNonLocked, getAuthorities (user.getRoles ())); } רשימת סטטי פרטית getAuthorities (תפקידי רשימה) {רשויות רשימה = ArrayList חדש (); עבור (תפקיד מחרוזת: תפקידים) {autorities.add (חדש SimpleGrantedAuthority (תפקיד)); } להחזיר רשויות; }}

8.2. הפעל את ספק האימות החדש

כדי לאפשר את שירות המשתמש החדש בתצורת Spring Security - עלינו פשוט להוסיף הפניה ל- UserDetailsService בתוך ה מנהל אימות אלמנט והוסף את UserDetailsService אפונה:

דוגמה 8.2.- מנהל האימות ו- UserDetailsService

לחלופין, באמצעות תצורת Java:

@Autowired פרטי MyUserDetailsService userDetailsService; תצורת הריק המוגנת על ידי @Override (AuthenticationManagerBuilder auth) זורקת חריג {auth.userDetailsService (userDetailsService); }

9. מסקנה

וגמרנו - שלם וכמעט תהליך רישום מוכן לייצור מיושם עם Spring Security ו- Spring MVC. בשלב הבא נדון בתהליך הפעלת החשבון החדש שנרשם על ידי אימות דוא"ל המשתמש החדש.

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

הַבָּא » הרשמה - הפעל חשבון חדש בדוא"ל « מדריך רישום אבטחה באביב הקודם