Spring Boot-没有数据库调用的JWT身份验证

时间:2019-03-06 17:30:45

标签: spring-boot spring-security jwt

是否有可能实现简单的JWT身份验证(不关心使令牌无效-我将在缓存中进行)而无需数据库调用来将用户加载到安全上下文中?我看到我当前的实现在每次调用api时都命中数据库(以将用户加载到安全上下文中)。在下面,您可以看到 JwtAuthenticationFilter 的一部分实现,扩展了 OncePerRequestFilter

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    try {
        String jwt = getJwtFromRequest(request);
        if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
            Long userId = tokenProvider.getUserIdFromJWT(jwt);
            UserDetails userDetails = customUserDetailsService.loadUserById(userId);
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
    } catch (Exception ex) {
        logger.error("Could not set user authentication in security context", ex);
    }
    filterChain.doFilter(request, response);
}

这是对数据库的调用,我希望避免使用(每次对api进行身份验证时都可以):

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    // This method is used by JWTAuthenticationFilter
    @Transactional
    public UserDetails loadUserById(Long id) {
        User user = userRepository.findById(id).orElseThrow(
            () -> new UsernameNotFoundException("User not found with id : " + id)
        );
        return UserPrincipal.create(user);
    }
}

我发现了一种仅使用用户ID 用户名和<来构建UserPrincipal对象(它实现 UserDetails 接口)的问题的解决方案强大的>授权机构,并且没有例如密码,我无法从JWT令牌本身读取该密码(其余的我可以读取),但是我不确定它是否安全,是否被认为是一种很好的实践解决方案( UserDetails 类需要密码字段,并将其存储为JWT(我认为并不明智)。我需要UserPrincipal实例(实现UserDetails接口)作为 UsernamePasswordAuthenticationToken 的参数来支持,如您在第一段中所见。

0 个答案:

没有答案