package org.visola.spring.security.tokenfilter.jwt;

import java.text.ParseException;
import java.util.Optional;

import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.visola.spring.security.tokenfilter.TokenService;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

public class JwtTokenService implements TokenService {

  private final AuthenticationJwtClaimsSetTransformer transformer;
  private final JWSSigner signer;
  private final JWSVerifier verifier;

  @Inject
  public JwtTokenService (AuthenticationJwtClaimsSetTransformer transformer,
                          @Value("${secret}") String secret) throws JOSEException {
    this.signer = new MACSigner(secret);
    this.verifier = new MACVerifier(secret);
    this.transformer = transformer;
  }

  @Override
  public String generateToken(Authentication authentication) {
    JWTClaimsSet claimsSet = transformer.getClaimsSet(authentication);
    SignedJWT signedJwt = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);
    try {
      signedJwt.sign(signer);
    } catch (JOSEException e) {
      throw new RuntimeException("Error while signing token.", e);
    }
    return signedJwt.serialize();
  }

  @Override
  public Optional<Authentication> verifyToken(Optional<String> token) {
    if (!token.isPresent()) {
      return Optional.empty();
    }

    SignedJWT signedJwt;
    JWTClaimsSet claimSet;
    try {
      signedJwt = SignedJWT.parse(token.get());
      if (!signedJwt.verify(verifier)) {
        throw new BadCredentialsException("Invalid token");
      }

      claimSet = signedJwt.getJWTClaimsSet();
    } catch (ParseException | JOSEException e) {
      throw new IllegalArgumentException("Error while parsing and verifying token.", e);
    }

    return Optional.of(transformer.getAuthentication(claimSet));
  }

}
@@ -1913,16 +1913,63 @@
 get());%0A
+      claimSet = signedJwt.getJWTClaimsSet();%0A%0A
       if
@@ -2072,55 +2072,8 @@
    %7D
-%0A%0A      claimSet = signedJwt.getJWTClaimsSet();
 %0A   
@@ -2210,24 +2210,172 @@
  e);%0A    %7D%0A%0A
+%0A    if (claimSet.getExpirationTime().getTime() %3C System.currentTimeMillis()) %7B%0A      throw new BadCredentialsException(%22Token is expired%22);%0A    %7D%0A%0A
     return O

Check for token expiration