首页 > 解决方案 > REST API调用中的所有用户都可以访问单个JWT令牌吗

问题描述

我一直在我的 Spring 应用程序中使用 JWT 令牌。我为每个客户创建了一个令牌,将用户名和密码作为参数传递给生成令牌,但所有用户都可以访问这个令牌。

例如:客户 3 必须获取他的数据http://example.com/api?customer=3

客户 3 必须在标头中传递一个令牌,他可以访问此 url..

但同样的令牌可以用来获取其他客户数据` http://example.com/api?customer=4

我该如何限制这个?

@Override
protected void doFilterInternal(HttpServletRequest request, 
                                HttpServletResponse response, 
                                FilterChain filterChain) 
                                        throws ServletException, IOException {
    try {

        String jwt = getJwt(request);
        if (jwt!=null && jwtProvider.validateJwtToken(jwt)) {
            String username = jwtProvider.getUserNameFromJwtToken(jwt);

            UserDetails userDetails = userService.loadUserByUsername(username);
            UsernamePasswordAuthenticationToken authentication 
                    = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
    } catch (Exception e) {
        logger.error("Can NOT set user authentication -> Message: {}", e.getMessage());
    }

    filterChain.doFilter(request, response);
}

private String getJwt(HttpServletRequest request) {
    String authHeader = request.getHeader("Authorization");

    if (authHeader != null && authHeader.startsWith("Bearer ")) {
        return authHeader.replace("Bearer ","");
    }

    return null;
}

public String generateJwtToken(Authentication auth) {
    UserPrinciple userPrinciple = (UserPrinciple) auth.getPrincipal();

    return Jwts.builder()
            .setSubject(userPrinciple.getUsername())
            .setIssuedAt(new Date())
            .setExpiration(expiryDate())
            .signWith(SignatureAlgorithm.HS512, "secretKey")
            .compact();
}

public Date expiryDate() {
    return new Date((new Date()).getTime() + 15 * 60 * 1000);
}

public boolean validateJwtToken(String authToken) {
    try {
        Jwts.parser().setSigningKey("secretkey").parseClaimsJws(authToken);
        return true;
    } catch (SignatureException e) {
        logger.error("Invalid JWT signature -> Message: {} ", e.getMessage());
    } catch (MalformedJwtException e) {
        logger.error("Invalid JWT token -> Message: {}", e.getMessage());
    } catch (ExpiredJwtException e) {
        logger.error("Expired JWT token -> Message: {}", e.getMessage());
    } catch (UnsupportedJwtException e) {
        logger.error("Unsupported JWT token -> Message: {}", e.getMessage());
    } catch (IllegalArgumentException e) {
        logger.error("JWT claims string is empty -> Message: {}", e.getMessage());
    }

    return false;
}

public String getUserNameFromJwtToken(String token) {
    return Jwts.parser()
                        .setSigningKey("secretKey")
                        .parseClaimsJws(token)
                        .getBody().getSubject();
}

标签: javaspring-bootrestspring-securityjwt

解决方案


推荐阅读