【发布时间】:2017-10-05 20:42:17
【问题描述】:
我在使用 Spring Security 和 Mongo Db 时遇到了一种相当奇怪的行为。
我有一个在 Mongo 中持久存在的客户用户实体:
@Document(collection = "user")
public class User {
@Id
private ObjectId id;
private String username;
...
}
我实现了一个 UserService,它允许以一种相当常见的方式持久化这些实体:
@Service
public class UserServiceImpl implements UserService {
@Override
public void save(User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
user.setAccountNonExpired(true);
user.setAccountNonLocked(true);
user.setCredentialsNonExpired(true);
user.setEnabled(true);
user.addRole(roleRepository.findByName("USER"));
userRepository.save(user);
}
...
}
我还有一个 SecurityService 实现:
@Service
public class SecurityServiceImpl implements SecurityService {
@Override
public void autologin(String username, String password) { ... }
}
还有一个 UserDetailsService:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
user = userRepository.findByEmail(username);
if (user == null) {
log.warn("Login attempt with unknown username");
throw new UsernameNotFoundException("not found");
}
}
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Role role : user.getRoles()) {
grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
user.isEnabled(), user.isAccountNonExpired(),
user.isCredentialsNonExpired(), user.isAccountNonLocked(),
grantedAuthorities);
}
在我的控制器中,我有类似的东西
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(HttpServletRequest request, Model model, String error,
String logout, Principal principal) { ... }
这很好用。我可以注册用户,登录,注销,重新登录。信息保留在 Mongo 中并正确加载。一切似乎都很好,直到我尝试实施重置密码..
我在我的 UserServiceImpl 类中实现了简单的方法来执行此操作,但即使简单地使用以下实现,也会发生相当奇怪的行为:
@Override
public void updateUser(User user) {
userRepository.save(user);
}
调用此方法后,如果我退出,我将无法再登录。我可以重新启动我的 spring-boot 应用程序,但仍然无法登录。
这很奇怪,因为我可以看到 Mongo 中的 JSON 文档没有改变。当我意识到如果我在 Mongo 中手动编辑相关文档(不执行任何实际更改,只需删除和添加相同的字符并保存它)之后,这变得很疯狂,然后登录再次工作!
如果有帮助:
MongoDB shell 版本:3.2.13,spring boot 1.4.1.RELEASE
有什么办法解决这个问题吗?
【问题讨论】:
标签: spring mongodb spring-mvc spring-boot spring-security