我正在尝试使用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
类中调用它时,它不起作用
答案 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 method的AuthenticationManagerBuilder
,并以某种方式注册您刚刚构建的AuthenticationManager
。
阅读topical guide : Spring Security Architecture,以更深入地了解Spring Security。