Registreringsprosessen med vårsikkerhet

Denne artikkelen er en del av en serie: • Opplæringsveiledning for vårsikkerhetsregistrering

• Registreringsprosessen med vårsikkerhet (nåværende artikkel) • Registrering - Aktiver en ny konto via e-post

• Vårsikkerhetsregistrering - Send bekreftelses-e-post på nytt

• Registrering med vårsikkerhet - passordkoding

• Registrerings-API-et blir RESTful

• Spring Security - Tilbakestill passordet ditt

• Registrering - Passordstyrke og regler

• Oppdatere passordet ditt

1. Oversikt

I denne artikkelen implementerer vi en grunnleggende registreringsprosess med Spring Security. Dette bygger på konsepter som ble utforsket i forrige artikkel, hvor vi så på innlogging.

Målet her er å legge til en full registreringsprosess som gjør det mulig for en bruker å registrere seg, validere og vedvare brukerdata.

2. Registreringssiden

Først - la oss implementere en enkel registreringsside som vises følgende felt:

  • Navn (fornavn og etternavn)
  • e-post
  • passord (og passordbekreftelsesfelt)

Følgende eksempel viser en enkel registrering.html side:

Eksempel 2.1.

skjema

først

Valideringsfeil

siste

Valideringsfeil

e-post

Valideringsfeil

passord

Valideringsfeil

bekreft send innlogging

3.Brukerens DTO-objekt

Vi trenger en Dataoverføringsobjekt for å sende all registreringsinformasjonen til vår-backend. De DTO objektet skal ha all informasjon vi trenger senere når vi oppretter og fyller ut vår Bruker gjenstand:

offentlig klasse UserDto {@NotNull @NotEmpty privat streng fornavn; @NotNull @NotEmpty privat strengnavn; @NotNull @NotEmpty privat strengpassord; private String matchingPassword; @NotNull @NotEmpty privat streng-e-post; // standard getters og setters}

Legg merke til at vi brukte standard javax.validation merknader på feltene til DTO-objektet. Senere skal vi også implementere våre egne tilpassede valideringskommentarer for å validere formatet til e-postadressen samt for passordbekreftelsen. (se Avsnitt 5)

4. Registreringskontrolløren

EN Melde deg på lenke på Logg Inn siden tar brukeren til registrering side. Denne bakenden for den siden bor i registreringskontrolleren og er kartlagt til "/bruker registrering":

Eksempel 4.1. - Den showRegistration Metode

@GetMapping ("/ bruker / registrering") offentlig String showRegistrationForm (WebRequest-forespørsel, modellmodell) {UserDto userDto = ny UserDto (); model.addAttribute ("bruker", userDto); returner "registrering"; }

Når kontrolleren mottar forespørselen "/bruker registrering", det skaper det nye UserDto objekt som vil sikkerhetskopiere registrering form, binder den og returnerer - ganske grei.

5. Validering av registreringsdata

Neste - la oss se på valideringene som kontrolleren vil utføre når du registrerer en ny konto:

  1. Alle obligatoriske felt er fylt ut (Ingen tomme eller null felt)
  2. E-postadressen er gyldig (velformet)
  3. Passordbekreftelsesfeltet samsvarer med passordfeltet
  4. Kontoen eksisterer ikke allerede

5.1. Den innebygde valideringen

For de enkle kontrollene bruker vi utmerkelser for validering av bønne på DTO-objektet - merknader som @Ikke null, @Ikke tom, etc.

For å utløse valideringsprosessen, vil vi bare kommentere objektet i kontrollerlaget med @Gyldig kommentar:

offentlig ModelAndView registerUserAccount (@ModelAttribute ("bruker") @Valid UserDto userDto, HttpServletRequest-forespørsel, feilfeil) {...}

5.2. Tilpasset validering for å sjekke e-postgyldighet

Neste - la oss validere e-postadressen og sørge for at den er velformet. Vi skal bygge en tilpasset validator for det, så vel som en egendefinert valideringskommentar - la oss kalle det @ValidEmail.

En rask sidenote her - vi ruller vår egen tilpassede kommentar i stedet for dvalemodus@Email fordi dvalemodus vurderer det gamle formatet for intranettadresser: [e-postbeskyttet] som gyldig (se artikkelen om Stackoverflow), noe som ikke er bra.

Her er e-postvalideringsnotatet og den tilpassede validatoren:

Eksempel 5.2.1. - Den tilpassede merknaden for validering av e-post

@Target ({TYPE, FIELD, ANNOTATION_TYPE}) @Retention (RUNTIME) @Constraint (validatedBy = EmailValidator.class) @Documented public @interface ValidEmail {Strengmelding () standard "Ugyldig e-post"; Klasse [] grupper () standard {}; Klasse [] nyttelast () standard {}; }

Merk at vi har definert merknaden på FELT nivå - siden det er der det gjelder konseptuelt.

Eksempel 5.2.2. - Tollen Send e-post til Validator:

offentlig klasse EmailValidator implementerer ConstraintValidator {privat mønster mønster; privat Matcher matcher; privat statisk sluttstreng EMAIL_PATTERN = "^ [_ A-Za-z0-9 - +] + (. [_ A-Za-z0-9 -] +) * @" + "[A-Za-z0-9 -] + (. [A-Za-z0-9] +) * (. [A-Za-z] {2,}) $ "; @Override public void initialize (ValidEmail constraintAnnotation) {} @Override public boolean isValid (String email, ConstraintValidatorContext context) {return (validateEmail (email)); } privat boolsk validateEmail (streng e-post) {mønster = Pattern.compile (EMAIL_PATTERN); matcher = mønster. matcher (e-post); retur matcher.matches (); }}

La oss nå bruk den nye kommentaren på vår UserDto gjennomføring:

@ValidEmail @NotNull @NotEmpty privat streng-e-post;

5.3. Bruke egendefinert validering for passordbekreftelse

Vi trenger også en tilpasset kommentar og validator for å sikre at passord og matchingPassword felt samsvarer med:

Eksempel 5.3.1. - Den egendefinerte merknaden for validering av passordbekreftelse

@Target ({TYPE, ANNOTATION_TYPE}) @Retention (RUNTIME) @Constraint (validatedBy = PasswordMatchesValidator.class) @Documented public @interface PasswordMatches {Strengmelding () standard "Passord samsvarer ikke"; Klasse [] grupper () standard {}; Klasse [] nyttelast () standard {}; }

Legg merke til at @Mål kommentar indikerer at dette er en TYPE nivåkommentar. Dette er fordi vi trenger hele UserDto protesterer mot å utføre valideringen.

Den egendefinerte validatoren som kalles ved denne kommentaren, vises nedenfor:

Eksempel 5.3.2. De PasswordMatchesValidator Tilpasset validator

offentlig klasse PasswordMatchesValidator implementerer ConstraintValidator {@Override public void initialize (PasswordMatches constraintAnnotation) {} @Override public boolean isValid (Object obj, ConstraintValidatorContext context) {UserDto user = (UserDto) obj; returner user.getPassword (). tilsvarer (user.getMatchingPassword ()); }}

Nå, den @PasswordMatches merknader bør brukes på vår UserDto gjenstand:

@PasswordMatches offentlig klasse UserDto {...}

Alle egendefinerte valideringer blir selvfølgelig evaluert sammen med alle standardkommentarer når hele valideringsprosessen kjører.

5.4. Kontroller at kontoen ikke allerede eksisterer

Den fjerde sjekken vi implementerer er å verifisere at e-post kontoen eksisterer ikke allerede i databasen.

Dette utføres etter at skjemaet er validert, og det gjøres ved hjelp av UserService gjennomføring.

Eksempel 5.4.1. - Kontrolleren createUserAccount Metode Kaller UserService Object

@PostMapping ("/ bruker / registrering") offentlig ModelAndView registerUserAccount (@ModelAttribute ("bruker") @Valid UserDto userDto, HttpServletRequest-forespørsel, feilfeil) {prøv {User registered = userService.registerNewUserAccount (userDto); } catch (UserAlreadyExistException uaeEx) {mav.addObject ("melding", "Det finnes allerede en konto for brukernavnet / e-postadressen."); retur mav; } // resten av implementeringen} 

Eksempel 5.4.2. - BrukerService Sjekker for dupliserte e-poster

@Service offentlig klasse UserService implementerer IUserService {@Autowired private UserRepository repository; @Transactional @Override public User registerNewUserAccount (UserDto userDto) kaster UserAlreadyExistException {if (emailExist (userDto.getEmail ())) {throw new UserAlreadyExistException ("Det er en konto med den e-postadressen:" + userDto.getEmail ()); } ... // resten av registreringsoperasjonen} privat boolsk emailExist (streng e-post) {return userRepository.findByEmail (email)! = null; }}

UserService er avhengig av UserRepository klasse for å sjekke om en bruker med en gitt e-postadresse allerede finnes i databasen.

Nå - den faktiske implementeringen av UserRepository i utholdenhetslaget er ikke relevant for den nåværende artikkelen. En rask måte er selvfølgelig å bruke Spring Data til å generere lagringslaget.

6. Vedvarende data og etterbehandling av skjemabehandling

Til slutt - la oss implementere registreringslogikken i kontrollerlaget vårt:

Eksempel 6.1.1. - Den Registrer Konto Metode i kontrolleren

@PostMapping ("/ bruker / registrering") offentlig ModelAndView registerUserAccount (@ModelAttribute ("bruker") @Valid UserDto userDto, HttpServletRequest-forespørsel, feilfeil) {prøv {User registered = userService.registerNewUserAccount (userDto); } catch (UserAlreadyExistException uaeEx) {mav.addObject ("melding", "Det finnes allerede en konto for brukernavnet / e-postadressen."); retur mav; } returner ny ModelAndView ("successRegister", "user", userDto); } 

Ting å legge merke til i koden ovenfor:

  1. Kontrolleren returnerer a ModelAndView objekt som er praktisk klasse for sending av modelldata (bruker) bundet til utsikten.
  2. Den behandlingsansvarlige vil omdirigere til registreringsskjemaet hvis det er noen feil som er angitt på valideringstidspunktet.

7.De UserService - Registrer operasjon

La oss fullføre implementeringen av registreringsoperasjonen i UserService:

Eksempel 7.1. De IUserService Grensesnitt

offentlig grensesnitt IUserService {User registerNewUserAccount (UserDto userDto) kaster UserAlreadyExistException; }

Eksempel 7.2. - Den UserService Klasse

@Service offentlig klasse UserService implementerer IUserService {@Autowired private UserRepository repository; @Transactional @Override public User registerNewUserAccount (UserDto userDto) kaster UserAlreadyExistException {if (emailExists (userDto.getEmail ())) {throw new UserAlreadyExistException ("Det er en konto med den e-postadressen: + userDto.getEmail ());} bruker bruker = ny bruker (); bruker.setFirstName (userDto.getFirstName ()); bruker.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. Laster inn brukerinformasjon for sikkerhetsinnlogging

I vår forrige artikkel brukte pålogging hardkodede referanser. La oss endre det og bruke den nylig registrerte brukerinformasjonen og legitimasjon. Vi implementerer en skikk UserDetailsService for å sjekke legitimasjonen for pålogging fra utholdenhetslaget.

8.1. Tollen UserDetailsService

La oss starte med den tilpassede implementeringen av tjenestene for brukerdetaljer:

@Service @Transactional public class MyUserDetailsService implementerer UserDetailsService {@Autowired private UserRepository userRepository; // offentlige UserDetails loadUserByUsername (streng e-post) kaster UsernameNotFoundException {User user = userRepository.findByEmail (email); if (user == null) {throw new UsernameNotFoundException ("Ingen bruker funnet med brukernavn:" + e-post); } boolsk aktivert = sann; boolsk kontoNonExpired = true; boolsk legitimasjonNonExpired = true; boolsk kontoNonLocked = true; returner ny org.springframework.security.core.userdetails.User (user.getEmail (), user.getPassword (). toLowerCase (), aktivert, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthorities (user.getRoles ())); } privat statisk liste getAuthorities (listeroller) {Liste myndigheter = ny ArrayList (); for (String rolle: roller) {autoriteter.add (ny SimpleGrantedAuthority (rolle)); } returmyndigheter; }}

8.2. Aktiver den nye godkjenningsleverandøren

For å aktivere den nye brukertjenesten i Spring Security-konfigurasjonen - trenger vi bare å legge til en referanse til UserDetailsService inne i godkjenningssjef element og legg til UserDetailsService bønne:

Eksempel 8.2. - Autentiseringsleder og UserDetailsService

Eller via Java-konfigurasjon:

@Autowired private MyUserDetailsService userDetailsService; @ Override beskyttet ugyldig konfigurasjon (AuthenticationManagerBuilder auth) kaster Unntak {auth.userDetailsService (userDetailsService); }

9. Konklusjon

Og vi er ferdige - en komplett og nesten produksjonsklar registreringsprosess implementert med Spring Security og Spring MVC. Deretter skal vi diskutere prosessen med å aktivere den nylig registrerte kontoen ved å bekrefte e-postadressen til den nye brukeren.

Implementeringen av denne REST-veiledningen om vårsikkerhet finner du i GitHub-prosjektet - dette er et formørkelsesbasert prosjekt, så det skal være enkelt å importere og kjøre som det er.

Neste » Registrering - Aktiver en ny konto via e-post « Forrige vårveiledning for sikkerhetsregistrering

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