当我尝试在运行时注册新用户时,AuthenticationManagerBuilder的内存身份验证不起作用

时间:2019-07-23 20:09:15

标签: spring-boot spring-security

我正在尝试使用AuthenticationManagerBuilder.inMemoryAuthentication(),以便在用户向/register页面发出发布请求后在运行时保存用户。但是,当我尝试在登录页面输入相同的用户名和密码时,凭据不会得到验证。

@Service
@Slf4j
@Transactional
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository; 

    @Autowired
    AuthenticationManagerBuilder auth;

    public void saveNewUser(User user) {

        UserDetails newUser = loadUserByUsername(user.getEmail()); 

        log.info("-----------------SAVE NEW USER CALLED---------------------");
        org.springframework.security.core.Authentication authentication = new UsernamePasswordAuthenticationToken(
                newUser, null, newUser.getAuthorities());

        SecurityContextHolder.getContext().setAuthentication(authentication); 

        try {

            log.info("------------------IN MEMORY AUTH SUCCESSFUL-----------------");
            log.info(user.getEmail() + user.getPassword() );
            auth.inMemoryAuthentication().withUser( user.getEmail() ).password(new BCryptPasswordEncoder().encode( user.getPassword() ))
                    .roles("USER");

        } catch (Exception e) { 
            log.info("--------------------NOT SUCCESFUL!----------------");
            e.printStackTrace();
        }

    }



    public UserDetails loadUserByUsername(String email)
      throws UsernameNotFoundException {

        User user = userRepository.findByEmail(email);
        if (user == null) {
            throw new UsernameNotFoundException(
              "No user found with username: "+ email);
        }
        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true; 
        return  new org.springframework.security.core.userdetails.User
          (
              user.getEmail(), 
              user.getPassword().toLowerCase(), enabled, accountNonExpired, 
              credentialsNonExpired, accountNonLocked, 
              getAuthorities(user.getRole())
              );
    }

    private static List<GrantedAuthority> getAuthorities (String role) {
        List<GrantedAuthority> authorities = new ArrayList<>(); 

        authorities.add(new SimpleGrantedAuthority(role));
        return authorities;
    }
}

因此,在我注册用户后,将调用savenewuser方法,并获得了该应用程序其他受保护部分的授权。我知道它被调用是因为当我查看调试控制台时会得到这些结果,

2019-07-23 12:48:15.203  INFO 47906 --- [nio-8080-exec-3] c.f.f.Security.MyUserDetailsService      : -----------------SAVE NEW USER CALLED---------------------
2019-07-23 12:48:15.203  INFO 47906 --- [nio-8080-exec-3] c.f.f.Security.MyUserDetailsService      : ------------------IN MEMORY AUTH SUCCESSFUL-----------------
2019-07-23 12:48:15.205  INFO 47906 --- [nio-8080-exec-3] c.f.f.Security.MyUserDetailsService      : asd@gmail.comasd

但是,当我导航到登录页面并输入与我注册时使用的相同的用户名和密码时,会出现错误。

inMemoryAuthentication()的工作原理 当我尝试在config方法中进行设置时。

    @Autowired
    private MyUserDetailsService userDetailsService;
    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 


        auth.inMemoryAuthentication().withUser("user").password( passwordEncoder().encode("password") ).roles("USER");

        auth.userDetailsService(userDetailsService);
    }

但是,当我在MyUserDetailsService类中调用它时,它不起作用

1 个答案:

答案 0 :(得分:1)

您可能误解了AuthenticationManagerBuilder的角色。它用于在应用程序启动时构建AuthenticationManager。像您所做的那样,通常在WebSecurityConfigurerAdapter的重写configure方法中使用

@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.inMemoryAuthentication().withUser("user").password( passwordEncoder().encode("password") ).roles("USER");
    auth.userDetailsService(userDetailsService);
}

如果您自己使用它,则必须在配置它后调用build methodAuthenticationManagerBuilder,并以某种方式注册您刚刚构建的AuthenticationManager

阅读topical guide : Spring Security Architecture,以更深入地了解Spring Security。