如何在Spring Security中检查每个请求的用户状态

问题描述 投票:0回答:2

我正在使用 spring security 并实现了 UserDetailsService ,它完美地处理了我的用户登录过程。

问题是这样的: 是否有一种标准方法来检查每个请求的数据库中的用户状态,以便如果用户的帐户状态更改为“锁定”或他的角色在他仍然登录时发生更改,应用程序会阻止他继续工作。

这里的问题是,我的自定义 UserDetailsService 类中的“public UserDetails loadUserByUsername(String arg0)”仅在登录过程中调用,并且 userDetails 对象在登录过程执行后保留数据,并且 userDetails 信息不保存新鲜。

我可以通过一些解决方法来解决这个问题,例如从数据库获取用户对象并通过侦听器检查其状态。但我觉得 Spring Security 可能对这种情况有一个通用的解决方案。

请帮忙。谢谢。

java spring spring-mvc spring-security
2个回答
1
投票

基本思想是使用自定义的

SecurityContextRepository
,它会丢弃保存在http会话中的用户详细信息。

有关完整示例和工作项目,请查看我对类似问题的回答:Spring Security 在运行时注销用户


0
投票

这个解决方案在 Spring-boot 3.x(和 Spring Security 6.x)上对我有用:

每当您使用

@EnableWebSecurity
时,您可能需要设置标准
UserDetailsService
bean... 所以你应该有这样的东西:

@Bean
public UserDetailsService userDetailsService() {
    return username -> userRepository.findByUsername(username)
         .orElseThrow(() -> new UsernameNotFoundException("User not found"));
}

您可以更改它以支持您的其他过滤器(在我的例子中,我为每个

Status
添加了一个
User entity
枚举,以在服务请求之前检查用户是否为
Status.Active
):

@Bean
public UserDetailsService userDetailsService() {
    return username -> userRepository.findByUsernameAndStatus(username, Status.ACTIVE)
         .orElseThrow(() -> new UsernameNotFoundException("User not found or not Active"));
}

不用说,JPA 在实现具有多个字段的

findBy
查询时非常方便,如我的
UserRepository
:

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
    
    // Old method:
    Optional<User> findByUsername(String username);
    
    // New method:
    Optional<User> findByUsernameAndStatus(String username, Status status);
}

最后一点:

由于我实现了自己的 custom

UserService
,所以我修改了
findBy
方法中的
loadUserByUsername
,如下所示:

@Service
public class UserService implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) {
        User user = userRepository.findByUsernameAndStatus(username, Status.ACTIVE)
                .orElseThrow(() -> new UsernameNotFoundException("User not found or not Active"));
        return user;
    }

...
...

祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.