Proces registracije s proljetnom sigurnošću

Ovaj je članak dio serije: • Proljetni vodič za sigurnosnu registraciju

• Postupak registracije s proljetnom sigurnošću (trenutni članak) • Registracija - Aktivirajte novi račun e-poštom

• Proljetna sigurnosna registracija - ponovno pošaljite e-poštu za potvrdu

• Registracija s Spring Security - kodiranje lozinkom

• API za registraciju postaje RESTful

• Proljetna sigurnost - resetirajte lozinku

• Registracija - Snaga lozinke i pravila

• Ažuriranje lozinke

1. Pregled

U ovom ćemo članku implementirati osnovni postupak registracije u Spring Security. Ovo se nadovezuje na koncepte istražene u prethodnom članku, gdje smo pogledali prijavu.

Ovdje je cilj dodati puni postupak registracije koji omogućuje korisniku da se prijavi, provjeri valjanost i ustraje u korisničkim podacima.

2. Stranica za registraciju

Prvo - implementiramo jednostavno prikazivanje stranice za registraciju sljedeća polja:

  • Ime (ime i prezime)
  • e-mail
  • zaporka (i polje za potvrdu lozinke)

Sljedeći primjer pokazuje jednostavan registracija.html stranica:

Primjer 2.1.

oblik

prvi

Pogreška provjere

posljednji

Pogreška provjere

e-mail

Pogreška provjere

zaporka

Pogreška provjere

potvrdi prijava prijava

3.Korisnički DTO objekt

Trebamo Objekt prijenosa podataka za slanje svih podataka o registraciji na naš proljetni backend. The DTO Objekt bi trebao imati sve podatke koji će nam biti potrebni kasnije kada kreiramo i popunimo svoj Korisnik objekt:

javna klasa UserDto {@NotNull @NotEmpty private String firstName; @NotNull @NotEmpty privatni niz lastName; @NotNull @NotEmpty lozinka privatnog niza; private String matchingPassword; @NotNull @NotEmpty privatni niz e-pošte; // standardni geteri i postavljači}

Primijetimo da smo koristili standard javax.valifikacija napomene na poljima DTO objekta. Kasnije ćemo također implementirati vlastite napomene o provjeri valjanosti za provjeru formata adrese e-pošte, kao i za potvrdu lozinke. (vidjeti Odjeljak 5)

4. Kontrolor registracije

A Prijava link na prijaviti se stranica odvest će korisnika na registracija stranica. Ovaj zadnji kraj te stranice živi u upravljaču za registraciju i preslikava se na "/Registracija korisnika":

Primjer 4.1. - The showRegistracija Metoda

@GetMapping ("/ korisnik / registracija") javni niz showRegistrationForm (zahtjev web-zahtjeva, model modela) {UserDto userDto = new UserDto (); model.addAttribute ("korisnik", userDto); vratiti "registraciju"; }

Kad kontrolor primi zahtjev "/Registracija korisnika", stvara novo UserDto objekt koji će podržati registracija oblik, veže ga i vraća - prilično izravno.

5. Provjera valjanosti podataka o registraciji

Dalje - pogledajmo provjere valjanosti koje će kontroler izvršiti prilikom registracije novog računa:

  1. Sva obavezna polja su popunjena (Nema praznih ili nula polja)
  2. Adresa e-pošte je valjana (dobro oblikovana)
  3. Polje za potvrdu lozinke podudara se s poljem lozinke
  4. Račun već ne postoji

5.1. Ugrađena provjera valjanosti

Za jednostavne provjere upotrijebit ćemo napomene za provjeru graha izvan okvira na DTO objektu - bilješke poput @NotNull, @Nije praznoitd.

Da bismo pokrenuli postupak provjere valjanosti, jednostavno ćemo objekt u sloju kontrolera označiti znakom @Valid napomena:

javni ModelAndView registerUserAccount (@ModelAttribute ("korisnik") @Valid UserDto userDto, zahtjev HttpServletRequest, pogreške u pogreškama) {...}

5.2. Prilagođena provjera valjanosti za provjeru valjanosti e-pošte

Dalje - provjerimo valjanost adrese e-pošte i pobrinimo se da je dobro oblikovana. Gradit ćemo a prilagođeni validator za to, kao i napomena prilagođene provjere valjanosti - nazovimo to @ValidEmail.

Ovdje na brzinu - uvodimo vlastitu prilagođenu napomenu umjesto hibernatskog@E-mail jer Hibernate uzima u obzir stari format adresa intraneta: [e-pošta zaštićena] kao valjano (vidi članak Stackoverflow), što nije dobro.

Evo bilješke o provjeri valjanosti e-pošte i prilagođenog programa za provjeru valjanosti:

Primjer 5.2.1. - Prilagođena bilješka za provjeru valjanosti e-pošte

@Target ({TYPE, FIELD, ANNOTATION_TYPE}) @Retention (RUNTIME) @Constraint (validatedBy = EmailValidator.class) @Documented public @interface ValidEmail {String message () default "Invalid email"; Class [] groups () zadani {}; Klasa [] korisni teret () zadana {}; }

Imajte na umu da smo napomenu definirali na POLJE razina - budući da se tu primjenjuje konceptualno.

Primjer 5.2.2. - Običaj EmailValidator:

javna klasa EmailValidator implementira ConstraintValidator {privatni obrazac uzorka; privatno podudaranje Matchera; privatni statički završni niz EMAIL_PATTERN = "^ [_ A-Za-z0-9 - +] + (. [_ A-Za-z0-9 -] +) * @" + "[A-Za-z0-9 -] + (. [A-Za-z0-9] +) * (. [A-Za-z-z] {2,}) $ "; @Override javna void inicijalizacija (ValidEmail constraintAnnotation) {} @Override public boolean isValid (String email, ConstraintValidatorContext context) {return (validateEmail (email)); } privatna logička validateEmail (string e-pošte) {pattern = Pattern.compile (EMAIL_PATTERN); podudaranje = pattern.matcher (e-pošta); vratiti matcher.matches (); }}

Idemo sada upotrijebi novu napomenu na naš UserDto provedba:

@ValidEmail @NotNull @NotEmpty e-mail privatnog niza;

5.3. Korištenje prilagođene provjere valjanosti za potvrdu lozinke

Također trebamo prilagođenu napomenu i validator kako bismo bili sigurni da zaporka i odgovarajuća lozinka polja se podudaraju:

Primjer 5.3.1. - Prilagođena bilješka za provjeru potvrde lozinke

@Target ({TYPE, ANNOTATION_TYPE}) @Retention (RUNTIME) @Constraint (validatedBy = PasswordMatchesValidator.class) @Documented public @interface PasswordMatches {String message () default "Lozinke se ne podudaraju"; Class [] groups () zadani {}; Klasa [] korisni teret () zadana {}; }

Primijetite da @Cilj napomena označava da je ovo a TIP bilješka na razini. To je zato što nam treba cjelokupno UserDto objekt koji će izvršiti provjeru valjanosti.

Prilagođeni validator koji će biti pozvan ovom bilješkom prikazan je u nastavku:

Primjer 5.3.2. The PasswordMatchesValidator Prilagođeni validator

javna klasa PasswordMatchesValidator implementira ConstraintValidator {@Override javna void inicijalizacija (PasswordMatches constraintAnnotation) {} @Override javni boolean isValid (Object obj, ConstraintValidatorContext context) {UserDto user = (UserDto) obj; vrati user.getPassword (). jednako (user.getMatchingPassword ()); }}

Sada, @PasswordMatches napomenu treba primijeniti na naš UserDto objekt:

@PasswordMatches javne klase UserDto {...}

Sve se prilagođene provjere valjanosti vrednuju zajedno sa svim standardnim bilješkama kada se pokrene cijeli postupak provjere valjanosti.

5.4. Provjerite da račun već ne postoji

Četvrta provjera koju ćemo provesti je provjera da li e-mail račun već ne postoji u bazi podataka.

To se izvodi nakon što je obrazac potvrđen i to je učinjeno uz pomoć Korisnička usluga provedba.

Primjer 5.4.1. - Kontrolorov createUserAccount Metoda poziva Korisnička usluga Objekt

@PostMapping ("/ user / registration") public ModelAndView registerUserAccount (@ModelAttribute ("user") @Valid UserDto userDto, HttpServletRequest zahtjev, pogreške pogrešaka) {try {User registered = userService.registerNewUserAccount (userDto); } catch (UserAlreadyExistException uaeEx) {mav.addObject ("message", "Račun za to korisničko ime / e-adresu već postoji."); povratak mav; } // ostatak implementacije} 

Primjer 5.4.2. - KorisnikServis Provjerava duplicirane e-adrese

@Service javna klasa UserService implementira IUserService {@Autowired privatno spremište UserRepository; @Transactional @Override public User registerNewUserAccount (UserDto userDto) baca UserAlreadyExistException {if (emailExist (userDto.getEmail ())) {throw new UserAlreadyExistException ("Postoji račun s tom adresom e-pošte:" + userDto.getEmail); } ... // ostatak postupka registracije} private boolean emailExist (String email) {return userRepository.findByEmail (email)! = null; }}

UserService oslanja se na UserRepository klase da provjeri postoji li korisnik s danom adresom e-pošte u bazi podataka.

Sada - stvarna provedba UserRepository u sloju postojanosti nije relevantan za trenutni članak. Jedan od brzih načina je, naravno, korištenje Spring Data za generiranje sloja spremišta.

6. Trajna obrada podataka i dorada obrazaca

Na kraju - implementiramo logiku registracije u naš sloj kontrolera:

Primjer 6.1.1. - The Registrirajte račun Metoda u kontroleru

@PostMapping ("/ user / registration") public ModelAndView registerUserAccount (@ModelAttribute ("user") @Valid UserDto userDto, HttpServletRequest zahtjev, pogreške pogrešaka) {try {User registered = userService.registerNewUserAccount (userDto); } catch (UserAlreadyExistException uaeEx) {mav.addObject ("message", "Račun za to korisničko ime / e-adresu već postoji."); povratak mav; } vratiti novi ModelAndView ("successRegister", "user", userDto); } 

Stvari koje treba primijetiti u gornjem kodu:

  1. Kontrolor vraća a ModelAndView objekt koji je prikladna klasa za slanje podataka o modelu (korisnik) vezan za pogled.
  2. Upravljač će preusmjeriti na obrazac za registraciju ako postoje pogreške postavljene u vrijeme provjere valjanosti.

7.The Korisnička usluga - Registrirajte rad

Završimo provedbu postupka registracije u Korisnička usluga:

Primjer 7.1. The IUserService Sučelje

javno sučelje IUserService {User registerNewUserAccount (UserDto userDto) baca UserAlreadyExistException; }

Primjer 7.2. - The Korisnička usluga Razred

@Service javna klasa UserService implementira IUserService {@Autowired privatno spremište UserRepository; @Transactional @Override public User registerNewUserAccount (UserDto userDto) baca UserAlreadyExistException {if (emailExists (userDto.getEmail ())) {throw new UserAlreadyExistException ("Postoji račun s tom adresom e-pošte: + userDto.getEmail ();) user = new User (); user.setFirstName (userDto.getFirstName ()); user.setLastName (userDto.getLastName ()); user.setPassword (userDto.getPassword ()); user.setEmail (userDto.getEmail ()) ; user.setRoles (Arrays.asList ("ROLE_USER")); return repository.save (user);} private boolean emailExists (String email) {return userRepository.findByEmail (email)! = null;}}

8. Učitavanje korisničkih podataka za sigurnosnu prijavu

U našem prethodnom članku prijava je koristila tvrdo kodirane vjerodajnice. Promijenimo to i koristiti novoregistrirane korisničke podatke i vjerodajnice. Primijenit ćemo običaj UserDetailsService za provjeru vjerodajnica za prijavu iz sloja postojanosti.

8.1. Običaj UserDetailsService

Počnimo s implementacijom usluge prilagođenih korisničkih podataka:

@Service @Transactional javna klasa MyUserDetailsService implementira UserDetailsService {@Autowired private UserRepository userRepository; // javni UserDetails loadUserByUsername (String e-mail) baca UsernameNotFoundException {User user = userRepository.findByEmail (email); if (user == null) {throw new UsernameNotFoundException ("Nije pronađen nijedan korisnik s korisničkim imenom:" + e-pošta); } logička vrijednost = true; boolean accountNonExpired = true; logičke vjerodajniceNonExpired = true; boolean accountNonLocked = true; vrati novi org.springframework.security.core.userdetails.User (user.getEmail (), user.getPassword (). toLowerCase (), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthorities (user.getRoles ())); } privatni statički popis getAuthorities (uloge popisa) {Ovlasti popisa = novi ArrayList (); za (uloga u nizu: uloge) {Authority.add (nova SimpleGrantedAuthority (uloga)); } vlasti za povratak; }}

8.2. Omogućite novog davatelja autentičnosti

Da bismo omogućili novu korisničku uslugu u konfiguraciji Spring Security - jednostavno moramo dodati referencu na UserDetailsService unutar autentifikacija-upravitelj element i dodajte UserDetailsService grah:

Primjer 8.2.- Upravitelj provjere autentičnosti i UserDetailsService

Ili putem Java konfiguracije:

@Autowired private MyUserDetailsService userDetailsService; @Override zaštićena void konfiguracija (AuthenticationManagerBuilder auth) baca iznimku {auth.userDetailsService (userDetailsService); }

9. Zaključak

I gotovi smo - potpuno i gotovo postupak registracije spreman za proizvodnju implementiran s Spring Security i Spring MVC. Dalje ćemo razgovarati o procesu aktiviranja novoregistriranog računa provjerom e-pošte novog korisnika.

Implementaciju ovog vodiča Spring REST možete pronaći u projektu GitHub - ovo je projekt zasnovan na Eclipseu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.

Sljedeći » Registracija - Aktivirajte novi račun e-poštom « Prethodni proljetni vodič za sigurnosnu registraciju