Как выполнить автоматический вход после успешной регистрации при весенней загрузке? - PullRequest
0 голосов
/ 14 ноября 2018

Да, я знаю, этот вопрос уже задавался.Но в отношении этого вопроса у меня есть и другая проблема.Объект authenticationManager объекта AuthenticationManager в классе SecurityServiceImpl, который не аутентифицирует детали, из-за которых я застрял в этой точке.

Я пытался выдавать сообщение после каждого шага, с помощью которого я могу отслеживать конкретный код, работают ли они илинет, и я обнаружил в классе SecurityServiceImpl, что он не работает после этого кода

authenticationManager.authenticate(usernamePasswordAuthenticationToken);

Я не знаю, это только мое понимание.Помогите мне решить эту проблему и предоставьте мне, если у вас есть лучший фрагмент кода для решения этой конкретной проблемы.

SecurityConfiguration

package com.demo.practice.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);

    @Autowired
    private UserDetailsService userDetailsService;

      protected void configure(HttpSecurity http) throws Exception {
           http.authorizeRequests()
            .antMatchers("/","/register","/login").permitAll()
            .antMatchers("/student/**").hasAuthority("STUDENT")
            .antMatchers("/admin/**").hasAuthority("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin().loginPage("/login")
            .defaultSuccessUrl("/dashboard");
           http.csrf().disable();
        }



    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }

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

        @Bean
        public BCryptPasswordEncoder bCryptPasswordEncoder() {
            return new BCryptPasswordEncoder();
        }
}

UserServiceImpl

package com.demo.practice.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.demo.practice.model.Credentials;
import com.demo.practice.model.Role;
import com.demo.practice.model.User;
import com.demo.practice.repository.UserRepository;

@Service
public class UserServiceImpl implements UserServiceInterface {

    @Autowired
    private BCryptPasswordEncoder encoder;
    @Autowired
    UserRepository userRepo;

    @Override
    public void saveUser(User user,Credentials credential) {
        user.setCredential(credential);
        user.getCredential().setUsername(user.getEmail());
        user.getCredential().setRoles(Role.STUDENT);
        user.getCredential().setPassword(encoder.encode(user.getCredential().getPassword()));
        userRepo.save(user);
    }

    @Override
    public User findUserByEmail(String name) {
        User user=userRepo.findUserByEmail(name);
        return user;
    }

}

UserDetailsServiceImpl

package com.demo.practice.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.demo.practice.model.Credentials;
import com.demo.practice.repository.CredentialRepository;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    CredentialRepository credRepo;

    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Credentials credential =credRepo.findByUsername(username);
        List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
        grantedAuthorities.add(new SimpleGrantedAuthority(credential.getRoles().toString()));
         return new org.springframework.security.core.userdetails.User(credential.getUsername(), credential.getPassword(), grantedAuthorities);
    }

}

SecurityServiceImpl

package com.demo.practice.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

@Service
public class SecurityServiceImpl implements SecurityServiceInterface {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

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

    @Override
    public String findLoggedInUsername() {
        Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails();
        if (userDetails instanceof UserDetails) {
            return ((UserDetails)userDetails).getUsername();
        }

        return null;
    }

    @Override
    public void autologin(String username, String password) {
       System.out.println("in autologin "+username);
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
           System.out.println("in autologin at userdetails"+userDetails);
          logger.info("after userdetails "+userDetails);
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(),userDetails.getAuthorities());
        logger.info("in autologin after usernamepasswordauthentication! ", usernamePasswordAuthenticationToken);
         authenticationManager.authenticate(usernamePasswordAuthenticationToken);
         logger.info("after authentication manager ", usernamePasswordAuthenticationToken);
          if (usernamePasswordAuthenticationToken.isAuthenticated()) {
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            logger.debug(String.format("Auto login %s successfully!", username));
        }
        else System.out.println("auto login failed");
    }


}

1 Ответ

0 голосов
/ 15 ноября 2018

вам не хватает одной вещи, если вы хотите иметь сеанс аутентификации на основе, вам нужно добавить WebAuthenticationDetails к токену, например:

UsernamePasswordAuthenticationToken token =
                    new UsernamePasswordAuthenticationToken(principalUser, null, List.of(new SimpleGrantedAuthority(principalUser.getRole())));

token.setDetails(new WebAuthenticationDetails(request));
SecurityContextHolder.getContext().setAuthentication(token);

WebAuthenticationDetails из документа: Records the remote address and will also set the session Id if a session already exists (it won't create one).

для получения дополнительной информации о процессе входа / выхода взгляните на: https://github.com/pezetem/spring-security-angular-skeleton/blob/master/src/main/java/com/pezetem/blog/code/spring_security_custom_authorizers/security/SecurityController.java

ОБНОВЛЕНИЕ:

ОК, может быть другая причина, почему он не работаетдля тебя.Spring Security добавляет префикс по умолчанию к ролям.Это равно ROLE_.Это означает, что если у вас конечная точка, настроенная для роли .hasAuthority("STUDENT"), должна быть равна ROLE_STUDENT, взгляните на строку, где вы создаете пользователя, вы назначаете роль с помощью Role.STUDENT, а значение перечисления должно быть ROLE_STUDENTне STUDENT

...