Автоматический вход после регистрации с использованием DaoAuthenticationProvider - PullRequest
0 голосов
/ 01 ноября 2019

Я пытаюсь реализовать автоматический вход в систему после успешной регистрации в приложении весенней загрузки.

Для хранения пользовательских данных я использую Hibernate, а для аутентификации я использую DaoAuthenticationProvider. Хорошо работает логин для пользователей, которые уже есть в базе данных, а также регистрация нового пользователя. Не работает только автоматический вход после регистрации.

В качестве имени пользователя я использую электронную почту пользователя. Я попробовал несколько разных подходов, которые рекомендованы в Интернете. Никто из них не работал. В том числе:

Автоматический вход после успешной регистрации Как программно аутентифицировать пользователя в Spring Security с помощью DaoAuthenticationProvider https://www.baeldung.com/spring-security-auto-login-user-after-registration

Мой класс WebSecurityConifig:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private UserService userService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth               
                .userDetailsService(userService)
                .passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
                authorizeRequests()

                .antMatchers("/login", "/console/**", "/registerNewUser/**", "/resources/**", "/css/**").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .ignoringAntMatchers("/console/**")
                // Request zum Aufruf der Login-Seite
                .and().formLogin().loginPage("/login").failureUrl("/login?error=true").permitAll()
                .defaultSuccessUrl("/")
                .usernameParameter("email")
                .passwordParameter("password")
                .and().logout().permitAll()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login?logout");

        http.headers().frameOptions().sameOrigin().disable();

        http.sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry());
    }

    @Override
    public void configure(WebSecurity web) {
        web
                .ignoring()
                .antMatchers("/resources/static/**", "/css/**", "/js/**", "/img/**");
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
        auth.setUserDetailsService(userService);
        auth.setPasswordEncoder(bCryptPasswordEncoder);
        return auth;
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

    @Bean
    public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
        return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher());
    }

    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

Мой контроллер для регистрации нового пользователя:

@Controller
public class AccRegistrationController {

@Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private UserValidator userValidator;

    @Autowired
    private AuthenticationManager authenticationManager;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.setValidator(userValidator);
    }

    @GetMapping("registerNewUser")
    public String registerUser(Model model, HttpServletRequest request) {
        model.addAttribute("user", new User());
        request.getSession();
        return "accountRegistration/registration";
    }

    @PostMapping("registerNewUser")
    public String registerAccount(HttpServletRequest request, @Valid @ModelAttribute("user") User user, BindingResult bindingResult, Model model) {

        if (bindingResult.hasErrors()) {
            model.addAttribute("user", user);
            return "accountRegistration/registration";
        }
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setActivated(false);
        user.setRoles(roleService.findAllByRolename("ROLE_USER"));
        userService.saveUser(user);


        UsernamePasswordAuthenticationToken token = new 
        UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword());
 request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
        token.setDetails(new WebAuthenticationDetails(request));
        Authentication authentication = authenticationManager.authenticate(token);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return "redirect:registerNewUser?success";
    }
}

Мой класс UserService:

@Service
public class UserService implements UserDetailsService {

    private static final Logger logger = LoggerFactory.getLogger(Data.class);

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private SessionRegistry sessionRegistry;

    /* creates new user object and returns it with an auto generated id */
    public User saveUser(User user) {
        return userRepository.save(user);
    }


    public List<User> getAllUsers() {
        return userRepository.findAll();
    }


    public Optional<User> findUser(Integer id) {
        return userRepository.findById(id);
    }

    public User getUserByEmail(String email) {
        return userRepository.findUserByEmail(email);
    }

    public User getOne(Integer id) {
        return userRepository.getOne(id);
    }



    public User getCurrentUser() {
        return getUserByEmail(((org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal()).getUsername());
    }


    public org.springframework.security.core.userdetails.User getCurrentUserDetails() {
        return (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
    }


    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        User user = userRepository.findUserByEmail(email);
        if (Objects.isNull(user)) {
            throw new UsernameNotFoundException("Could not find the user for username " + email);
        }
        List<GrantedAuthority> grantedAuthorities = getUserAuthorities(user.getRoles());
        return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(),
                user.isEnabled(), true, true, user.isEnabled(), grantedAuthorities);
    }

    private List<GrantedAuthority> getUserAuthorities(Set<Role> roleSet) {
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (Role role : roleSet) {
            grantedAuthorities.add(new SimpleGrantedAuthority(role.getRolename()));
        }
        return grantedAuthorities;
    }

    public Collection<String> getLoggedInUsers() {
        return sessionRegistry.getAllPrincipals().stream()
                .filter(u -> !sessionRegistry.getAllSessions(u, false).isEmpty())
                .map(Object::toString)
                .collect(Collectors.toList());
    }

}

Я добавил несколько операторов println в AccRegistrationController к своемукод, чтобы узнать, в чем проблема, потому что не возникло ошибок во время / после процесса регистрации. Я обнаружил, что проблема должна быть в этой строке кода:

Authentication authentication = authenticationManager.authenticate(token);

Но я не могу сказать, что не так. Возможно, что-то не так с аутентификационным менеджером.

Что бы я ни заметил, метод "registerAccount" не выполняется до конца. Перенаправление не работает, и меня перенаправляют на страницу входа.

Надеюсь, вы поможете мне найти мою ошибку.

1 Ответ

0 голосов
/ 01 ноября 2019

Самый простой метод для входа в систему пользователя - это вызвать HttpServletRequest.login(String username, String password) метод.

Источник: https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/servletapi.html#servletapi-login

В AccRegistrationController.registerAccount вы можете заменить всю последнюю часть на эту

/*UsernamePasswordAuthenticationToken token = new 
        UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword());
 request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
        token.setDetails(new WebAuthenticationDetails(request));
        Authentication authentication = authenticationManager.authenticate(token);
        SecurityContextHolder.getContext().setAuthentication(authentication);
*/
request.login(user.getEmail(), user.getPassword());

Это начнет весь поток аутентификации Spring.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...