令牌的发送者未在标头中正确设置令牌,格式为“身份验证:承载your.jwt.token”。
如果存在承载,请将其从令牌中删除,然后将其传递给JWT流程引擎。
解决方法我有使用JVM支持JSON Web令牌的类来创建和验证JWT令牌
@Componentpublic class JwtTokenUtil implements Serializable { private static final long serialVersionUID = -3301605592208950415L; private Clock clock = DefaultClock.INSTANCE; @Value('${jwt.secret}') private String secret; @Value('${jwt.expiration}') private Long expiration; public String getUsernameFromToken(String token) {return getClaimFromToken(token,Claims::getSubject); } public Date getIssuedAtDateFromToken(String token) {return getClaimFromToken(token,Claims::getIssuedAt); } public Date getExpirationDateFromToken(String token) {return getClaimFromToken(token,Claims::getExpiration); } public <T> T getClaimFromToken(String token,Function<Claims,T> claimsResolver) {final Claims claims = getAllClaimsFromToken(token);return claimsResolver.apply(claims); } private Claims getAllClaimsFromToken(String token) {return Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); } private Boolean isTokenExpired(String token) {final Date expiration = getExpirationDateFromToken(token);return expiration.before(clock.now()); } private Boolean isCreatedBeforeLastPasswordReset(Date created,Date lastPasswordReset) {return (lastPasswordReset != null && created.before(lastPasswordReset)); } private Boolean ignoreTokenExpiration(String token) {return false; } public String generateToken(UserDetails userDetails) {Map<String,Object> claims = new HashMap<>();return doGenerateToken(claims,userDetails.getUsername()); } private String doGenerateToken(Map<String,Object> claims,String subject) {final Date createdDate = clock.now();final Date expirationDate = calculateExpirationDate(createdDate);return Jwts.builder() .setClaims(claims) .setSubject(subject) .setIssuedAt(createdDate) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS512,secret) .compact(); } public Boolean canTokenBeRefreshed(String token,Date lastPasswordReset) {final Date created = getIssuedAtDateFromToken(token);return !isCreatedBeforeLastPasswordReset(created,lastPasswordReset) && (!isTokenExpired(token) || ignoreTokenExpiration(token)); } public String refreshToken(String token) {final Date createdDate = clock.now();final Date expirationDate = calculateExpirationDate(createdDate);final Claims claims = getAllClaimsFromToken(token);claims.setIssuedAt(createdDate);claims.setExpiration(expirationDate);return Jwts.builder() .setClaims(claims) .signWith(SignatureAlgorithm.HS512,secret) .compact(); } public Boolean validateToken(String token,UserDetails userDetails) { User user = (User) userDetails;final String username = getUsernameFromToken(token);final Date created = getIssuedAtDateFromToken(token);return ( username.equals(user.getUsername())&& !isTokenExpired(token)&& !isCreatedBeforeLastPasswordReset(created,user.getLastPasswordResetDate())); } private Date calculateExpirationDate(Date createdDate) {return new Date(createdDate.getTime() + expiration * 1000); }}
但是验证令牌时出现此错误:
2018-12-27 16:57 [http-nio-1133-exec-6] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet].log(175) - Servlet.service() for servlet [dispatcherServlet] in context with path [/iCrypts] threw exceptionio.jsonwebtoken.MalformedJwtException: JWT strings must contain exactly 2 period characters. Found: 0 at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:235) at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481) at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:541) at com.tdk.security.JwtTokenUtil.getAllClaimsFromToken(JwtTokenUtil.java:55) at com.tdk.security.JwtTokenUtil.getClaimFromToken(JwtTokenUtil.java:48) at com.tdk.security.JwtTokenUtil.getUsernameFromToken(JwtTokenUtil.java:36) at com.tdk.security.JwtAuthorizationTokenFilter.doFilterInternal(JwtAuthorizationTokenFilter.java:58) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)