Spring MVC + AngularJS + JWT 令牌过期 - HowTo
Posted
技术标签:
【中文标题】Spring MVC + AngularJS + JWT 令牌过期 - HowTo【英文标题】:Spring MVC + AngularJS + JWT Token Expiration - 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 实现这一目标
【问题讨论】:
【参考方案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
【讨论】:
以上是关于Spring MVC + AngularJS + JWT 令牌过期 - HowTo的主要内容,如果未能解决你的问题,请参考以下文章
Spring MVC + AngularJS + JWT 令牌过期 - HowTo
使用 Spring MVC 和 AngularJS 的方法 DELETE
AngularJS和Spring MVC的Ajax GET错误
Spring MVC - AngularJS - 文件上传 - org.apache.commons.fileupload.FileUploadException