在 Mongo Db 中更新相关文档后 Spring 用户身份验证不起作用
Posted
技术标签:
【中文标题】在 Mongo Db 中更新相关文档后 Spring 用户身份验证不起作用【英文标题】:Spring user authentication does not work after updating related document in Mongo Db 【发布时间】: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
有什么办法解决这个问题吗?
【问题讨论】:
【参考方案1】:不确定,但我认为您在更新用户时错过了一件小事。 您在创建用户时加密了密码
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
我假设您在更新密码时也在更新密码。
但是更新用户时没有密码加密,正如我在您的 updateUser
方法中看到的那样(除非您在调用此方法之前已加密密码)。
如果我是正确的,那么我的建议是在更新用户数据时避免更新密码,并使用不同的方法来更改密码。
【讨论】:
以上是关于在 Mongo Db 中更新相关文档后 Spring 用户身份验证不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使用官方 C# 驱动程序在 Mongo DB 中进行更新插入
学习mongo系列修改器($inc/$set/$unset/$push/$pop/upsert)
如何在Mongo DB中使用arrayElemAt获取当前文档值