【问题标题】:Spring MVC + AngularJS + JWT Token Expiration - HowToSpring MVC + AngularJS + JWT 令牌过期 - HowTo
【发布时间】:2016-10-01 11:39:34
【问题描述】:

我想确保我的 JSON Web 令牌在可配置的时间后被撤销/过期,并且我进行了以下设置:

安全过滤器:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import yourwebproject2.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author: kameshr
 */
public class JWTTokenAuthFilter extends OncePerRequestFilter {
    private static List<Pattern> AUTH_ROUTES = new ArrayList<>();
    private static List<String> NO_AUTH_ROUTES = new ArrayList<>();
    public static final String JWT_KEY = "JWT-TOKEN-SECRET";

    static {
        AUTH_ROUTES.add(Pattern.compile("/api/*"));
        NO_AUTH_ROUTES.add("/api/user/authenticate");
        NO_AUTH_ROUTES.add("/api/user/register");
    }

    private Logger LOG = LoggerFactory.getLogger(JWTTokenAuthFilter.class);

    @Autowired
    private UserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String authorizationHeader = request.getHeader("authorization");
        String authenticationHeader = request.getHeader("authentication");
        String route = request.getRequestURI();

        // no auth route matching
        boolean needsAuthentication = false;

        for (Pattern p : AUTH_ROUTES) {
            if (p.matcher(route).matches()) {
                needsAuthentication = true;
                break;
            }
        }

        if(route.startsWith("/api/")) {
            needsAuthentication = true;
        }

        if (NO_AUTH_ROUTES.contains(route)) {
            needsAuthentication = false;
        }

        // Checking whether the current route needs to be authenticated
        if (needsAuthentication) {
            // Check for authorization header presence
            String authHeader = null;
            if (authorizationHeader == null || authorizationHeader.equalsIgnoreCase("")) {
                if (authenticationHeader == null || authenticationHeader.equalsIgnoreCase("")) {
                    authHeader = null;
                } else {
                    authHeader = authenticationHeader;
                    LOG.info("authentication: " + authenticationHeader);
                }
            } else {
                authHeader = authorizationHeader;
                LOG.info("authorization: " + authorizationHeader);
            }

            if (StringUtils.isBlank(authHeader) || !authHeader.startsWith("Bearer ")) {
                throw new AuthCredentialsMissingException("Missing or invalid Authorization header.");
            }

            final String token = authHeader.substring(7); // The part after "Bearer "
            try {
                final Claims claims = Jwts.parser().setSigningKey(JWT_KEY)
                        .parseClaimsJws(token).getBody();
                request.setAttribute("claims", claims);

                // Now since the authentication process if finished
                // move the request forward
                filterChain.doFilter(request, response);
            } catch (final Exception e) {
                throw new AuthenticationFailedException("Invalid token. Cause:"+e.getMessage());
            }
        } else {
            filterChain.doFilter(request, response);
        }
    }
}

创建身份验证令牌的方法:

String token = Jwts.builder().setSubject(user.getEmail())
                .claim("role", user.getRole().name()).setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, JWTTokenAuthFilter.JWT_KEY).compact();
        authResp.put("token", token);
        authResp.put("user", user);

上面我有我在 JWT 上使用的所有声明,我想请求在 x 时间后撤销令牌(如果可能的话,不活动)。

我如何使用 JWT / Spring MVC / Angular JS / Spring Security 实现这一目标

【问题讨论】:

    标签: javascript angularjs spring jwt


    【解决方案1】:

    设置令牌的过期时间

     String token = Jwts.builder()
         .setSubject(user.getEmail())
         .claim("role", user.getRole().name())
         .setIssuedAt(new Date())
         .setExpiration(expirationDate) 
         .signWith(SignatureAlgorithm.HS256, WTTokenAuthFilter.JWT_KEY)
         .compact();
    

    然后,parseClaimsJws 将引发 ExpiredJwtException 如果 currentTime>expirationDate

    撤销有效令牌是一项很难的技术,没有简单的解决方案:

    1) 在服务器中维护一个黑名单并针对每个请求进行比较

    2) 设置一个小的过期时间并发行新的token

    3) 在令牌中插入登录时间并比较是否符合您的条件

    4) 删除客户端的 jwt

    Ser Invalidating client side JWT session

    【讨论】:

      猜你喜欢
      • 2018-08-05
      • 2017-03-04
      • 2019-07-04
      • 2022-11-15
      • 2017-11-28
      • 2018-06-19
      • 2019-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多