Login automatica dopo la registrazione

di il
8 risposte

Login automatica dopo la registrazione

Ho realizzato un'app in cui gli utenti possono registrarsi oppure fare la login. Le fasi di registrazione e login funzionano correttamente ma ho un problema con la login automatica di un utente che si è appena registrato.
Al momento l'utente dopo essersi registrato deve fare la login e questo è molto scomodo e crea confusione.
Preferirei che dopo la fase di registrazione Spring Security eseguisse in automatico la login del nuovo utente.
Per fare questo ho aggiunto queste due semplici righe di codice ma ottengo "Errore: Impossibile aggiungere il nuovo utente nel database e/o eseguire il login dell'utente.":

GestioneUtentiSpringSecurity guss = new GestioneUtentiSpringSecurity();
guss.loadUserByUsername(nuovoUtente.getNome());
Ecco le classi su cui sto lavorando:

@Controller
public class ControlloPagineWeb {

    ...............

    @RequestMapping(value = "/registrazione", method = RequestMethod.GET)
    public String paginaRegistrazione(Model model) {
        CaratteriConsentiti cc = new CaratteriConsentiti();
        model.addAttribute("CaratteriConsentiti", cc);
        model.addAttribute("titolo", "Pagina di registrazione");
        UtenteForm form = new UtenteForm();
        model.addAttribute("UtenteForm", form);
        return "registrazione";
    }

    @RequestMapping(value = "/registrazione", method = RequestMethod.POST)
    public String saveRegister(Model model,
                               @ModelAttribute("UtenteForm") @Validated UtenteForm UtenteForm,
                               BindingResult result,
                               final RedirectAttributes redirectAttributes) {
        CaratteriConsentiti cc = new CaratteriConsentiti();
        model.addAttribute("CaratteriConsentiti", cc);
        model.addAttribute("titolo", "Pagina di registrazione");
        if (result.hasErrors()) {
            return "registrazione";
        }
        Utente nuovoUtente= null;
        try {
            BCryptPasswordEncoder password_crittografata = new BCryptPasswordEncoder();
            Utente utente = new Utente(
                    0L,
                    UtenteForm.getNomeUtenteForm(),
                    password_crittografata.encode(UtenteForm.getPasswordForm()),
                    true);
            nuovoUtente = utenteRepository.inserisciUtente(utente);
            // Si esegue la login dell'utente che si è appena registrato. 
            GestioneUtentiSpringSecurity guss = new GestioneUtentiSpringSecurity(); // NON FUNZIONA!!!!!!!!!!!!!!!!!!!!!!!
            guss.loadUserByUsername(nuovoUtente.getNome()); // NON FUNZIONA!!!!!!!!!!!!!!!!!!!!!!!
        }
        catch (Exception e) {
            model.addAttribute(
                    "erroreInserimentoDBMS",
                    "Errore: Impossibile aggiungere il nuovo utente nel database e/o eseguire il login dell'utente."
            );
            return "registrazione";
        }
        redirectAttributes.addFlashAttribute("utenteRegistrato", nuovoUtente);
        return "redirect:/registrazione-eseguita";
    }

    ....................

}

@Service
public class GestioneUtentiSpringSecurity implements UserDetailsService {

    @Autowired
    private UtenteRepository utenteRepository;

    @Autowired
    private RuoloRepository ruoloRepository;

    @Override
    public UserDetails loadUserByUsername(String nomeUtente) throws UsernameNotFoundException {
        Utente utente = this.utenteRepository.trovaUtente(nomeUtente);
        if (utente == null) {
            throw new UsernameNotFoundException("L'utente " + nomeUtente + " non è stato trovato nel database.");
        }
        List<String> ruoliUtente = this.ruoloRepository.trovaRuoliUtente(utente.getId());
        List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>();
        if (ruoliUtente != null) {
            for (String ruolo : ruoliUtente) {
                GrantedAuthority authority = new SimpleGrantedAuthority(ruolo);
                grantList.add(authority);
            }
        }
        UserDetails userDetails = (UserDetails) new User(utente.getNome(), utente.getPassword(), grantList);
        return userDetails;
    }

}
Dove sbaglio?
Come dovrei procedere?

8 Risposte

  • Re: Login automatica dopo la registrazione

    I tuoi utenti si registrano indicando la mail, giusto?
    Normalmente dovresti usare il Double opt-in: registrazione->invio mail di conferma->click sul link di attivazione nella mail di conferma.
    L'autenticazione quindi andrebbe comunque disconnessa dal flusso di registrazione
  • Re: Login automatica dopo la registrazione

    No, i miei utenti non si registrano con la mail.
  • Re: Login automatica dopo la registrazione

    Ho provato con questo codice ma nulla da fare, ottengo sempre lo stesso errore:
    
        @RequestMapping(value = "/registrazione", method = RequestMethod.POST)
        public String saveRegister(Model model,
                                   @ModelAttribute("UtenteForm") @Validated UtenteForm UtenteForm,
                                   BindingResult result,
                                   final RedirectAttributes redirectAttributes,
                                   HttpServletRequest request) {
            CaratteriConsentiti cc = new CaratteriConsentiti();
            model.addAttribute("CaratteriConsentiti", cc);
            model.addAttribute("titolo", "Pagina di registrazione");
            if (result.hasErrors()) {
                return "registrazione";
            }
            Utente nuovoUtente= null;
            try {
                BCryptPasswordEncoder password_crittografata = new BCryptPasswordEncoder();
                Utente utente = new Utente(
                        0L,
                        UtenteForm.getNomeUtenteForm(),
                        password_crittografata.encode(UtenteForm.getPasswordForm()),
                        true);
                nuovoUtente = utenteRepository.inserisciUtente(utente);
                autenticaUtente(nuovoUtente, request);
            }
            catch (Exception e) {
                model.addAttribute(
                        "erroreInserimentoDBMS",
                        "Errore: Impossibile aggiungere il nuovo utente nel database e/o eseguire il login dell'utente."
                );
                return "registrazione";
            }
            redirectAttributes.addFlashAttribute("utenteRegistrato", nuovoUtente);
            return "redirect:/registrazione-eseguita";
        }
    
        protected AuthenticationManager authenticationManager;
    
        private void autenticaUtente(Utente utente, HttpServletRequest request) {
            UserDetails user = costruzioneDettagliUser(utente);
            String nome = user.getUsername();
            String password = user.getPassword();
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(nome, password);
            // generate session if one doesn't exist
            request.getSession();
            token.setDetails(new WebAuthenticationDetails(request));
            Authentication utenteAutenticato = authenticationManager.authenticate(token);
            SecurityContextHolder.getContext().setAuthentication(utenteAutenticato);
        }
    
        public UserDetails costruzioneDettagliUser(Utente utente) {
            List<String> ruoliUtente = ruoloRepository.trovaRuoliUtente(utente.getId());
            List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>();
            if (ruoliUtente != null) {
                for (String ruolo : ruoliUtente) {
                    GrantedAuthority authority = new SimpleGrantedAuthority(ruolo);
                    grantList.add(authority);
                }
            }
            UserDetails userDetails = (UserDetails) new User(utente.getNome(), utente.getPassword(), grantList);
            return userDetails;
        }
    
    
  • Re: Login automatica dopo la registrazione

    Ho risolto
  • Re: Login automatica dopo la registrazione

    Toki ha scritto:


    I tuoi utenti si registrano indicando la mail, giusto?
    Normalmente dovresti usare il Double opt-in: registrazione->invio mail di conferma->click sul link di attivazione nella mail di conferma.
    L'autenticazione quindi andrebbe comunque disconnessa dal flusso di registrazione
    Non ho creato la registrazione tramite email perché non avendo un server fisico ho pensato che sarebbe stato impossibile verificare l'invio delle email con i relativi link.
    E' giusto quello che ho scritto oppure con IntelliJ/Spring posso inviare un'email ad una casella reale?
    Se decido di aggiungere l'email in fase di registrazione devo prima mettere su un server, giusto?
    Tu come procedi?
    grazie
  • Re: Login automatica dopo la registrazione

    iBaffiPro ha scritto:


    Non ho creato la registrazione tramite email perché non avendo un server fisico ho pensato che sarebbe stato impossibile verificare l'invio delle email con i relativi link.
    E' giusto quello che ho scritto oppure con IntelliJ/Spring posso inviare un'email ad una casella reale?
    Se decido di aggiungere l'email in fase di registrazione devo prima mettere su un server, giusto?
    Ma no, che stai dicendo ....

    Allora: innanzitutto se vuoi gestire l'invio di una email per la conferma registrazione devi avere dei campi in più nella tabella utenti. Sicuramente serve un campo che tiene un codice numerico/alfanumerico bello lungo e generato a caso tipo 4SF9QM7QPUYYZZSH88YNV2ZLGLD58B. E poi anche una data di registrazione (dovresti già averla messa) per fare un controllo a livello temporale.

    La email dovrà contenere un link del tipo es.:

    http://nomehostblabla/conferma-registrazione/4SF9QM7QPUYYZZSH88YNV2ZLGLD58B

    La email ovviamente la devi spedire all'utente che si sta registrando. Su un ambiente di "sviluppo" (es. tua macchina a casa) dovrai usare il SMTP che usi normalmente per la tua posta (quello del tuo provider, tipicamente). Su un hosting reale, è l'hosting stesso che ti fornisce un server SMTP (se previsto dal pacchetto) di cui ti dà le credenziali. Generalmente sugli hosting il SMTP è o sul localhost (dove già gira l'applicazione) o comunque su una macchina che è nella rete locale interna all'hosting. E' improbabile che sia "fuori" dall'hosting.

    Su sviluppo in realtà non è realmente necessario che mandi la email (es. a te), puoi farlo per prova ovviamente. Ma banalmente basta che logghi a livello DEBUG quel codice lungo e poi componi tu l'url nel browser verso la tua webapp sul localhost.

    Pertanto è ovvio che devi avere configurazioni differenti tra "sviluppo" e "produzione" ma a questo dovresti averci GIÀ pensato ... altrimenti non ci siamo ..

    Riguardo la email, la devi creare in modo molto accurato. Come contenuto, header interni della email, oggetto, from, ecc.... per limitare il più possibile l'eventualità che venga considerata Spam. Tipo: se non metti un from, è altamente probabile che un anti-spam di un utente te la blocca subito.
  • Re: Login automatica dopo la registrazione

    Tutto molto interessante, mi hai convinto, aggiungo anche la mail in fase di registrazione ma non prima di aver risolto tutti gli altri problemi che circolano nella mia webapp. Spring Boot non è così complesso come sembra ma è difficile imparare a muoversi tra il framework perché non ci sono libri e neppure della documentazione valida/aggiornata. Ho perso quasi un giorno per fare un'autenticazione automatica di un utente che si sta registrando.
    Grazie infinite
  • Re: Login automatica dopo la registrazione

    iBaffiPro ha scritto:


    è difficile imparare a muoversi tra il framework perché non ci sono libri e neppure della documentazione valida/aggiornata.
    Ma ... stai scherzando vero??
    Prima di tutto c'è tutta la documentazione reference/javadoc ufficiale (e aggiungo: aggiornatissima) di tutti i prodotti Spring (Framework, Boot, Security, Data, Cloud, ecc...).
    Poi ci sono un sacco di libri su Spring tra cui principalmente e preferibilmente quelli delle case editrici: Manning, Apress, O'Reilly, Packt.
Devi accedere o registrarti per scrivere nel forum
8 risposte