spring-boot - 如何从 Spring Boot 中的 Scheduled 更新用户信息
问题描述
当我尝试将用户保存在计划任务中,然后通过 Authentication.getPrincipal() 在控制器中访问它时,尽管底层数据库记录发生更改,但它不会得到更新。
@Scheduled(fixedRate = 10_000)
public void job() {
User user = userRepo.findById(1).get();
user.setEmail("someNewEmail@gmail.com");
userRepo.save(user);
}
我使用 Spring Security,并且我相信用户的信息会以某种方式缓存在 SecurityContextHolder 中,因此不允许我使用已保存用户的更新值。
此外,如果我执行 SignOut - SignIn 数据会更新,但这不能被视为解决方案。
作为一种解决方法,我尝试使用自动装配的 EntityManager 并在获取数据之前用用户刷新记录,但这假设我应该为需要获取用户的每个请求执行此操作。也不是最好的解决方案
除用户外的其他实体保存良好
解决方案
我最终获得了一个带有容器的服务,该容器包含我需要更改其数据的用户。
@Service
@Getter
@Setter
public class AuthService {
private List<User> users = new CopyOnWriteArrayList<>();
}
而且我还按照 Mehdi 的建议实施了一个过滤器。
public class AuthFilter extends GenericFilterBean {
@Autowired
private AuthService authService;
@Autowired
private UserRepository userRepo;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || !auth.isAuthenticated() || !(auth.getPrincipal() instanceof UserDetails)) {
chain.doFilter(request, response);
return;
}
User currUser = ... // getting current user from auth
if (authService.getUsers().contains(currUser)) {
UserDetails details = myUserDetailsService.loadUserByUsername(currUser.getFirstName());
Authentication updatedAuth = new UsernamePasswordAuthenticationToken(details, currUser.getPassword(), details.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(updatedAuth);
authService.getUsers().remove(currUser);
}
chain.doFilter(request, response);
}
}
很遗憾,spring 没有提供一个包含所有 Authentication 对象的容器来使更改用户更容易。或者也许我没找到
推荐阅读
- python - 小时和时间转换为某种格式
- unit-testing - 有没有办法在 Quasar 中使用全局笑话模拟?
- node.js - 节点流:如何转换 Buffer 流以将数组写入输出
- flutter - 共享首选项中的颤振功能
- python - Python:我有一个列表,我想将它添加到列表的每个元素中
- sql - 行存储功能上的 Sql Server 2019 批处理模式不起作用
- scala - 将 Spark DataFrame 导出到 S3
- awk - Bash - awk 函数是否具有内置的 julian day 函数?
- json - 如何将以下 json 解组为 golang 结构
- svelte - 在应用程序的入口点调用 i18n.js 文件 | 苗条-i18n