5

I'm trying to implement jwt based authentication to expose my REST api using spring boot, but I'm facing an issue with JWT expiration date.It is always throwing "ExpiredJwtException" even i have set expiration time. I have provided code, please let me know if someone find exact issue and solution. Thanks.

git repository https://github.com/asim-ch/JWT-authentication-with-spring-boot

Authentication Filter

public class JWTAuthenticationFilter extends OncePerRequestFilter {

   @Autowired
   TokenProvider tokenProvider;
   @Autowired
   CustomUserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, 
    HttpServletResponse httpServletResponse, FilterChain filterChain) throws 
    ServletException, IOException {
        try {
            String jwt = getJwt(httpServletRequest);
            if (jwt!=null && tokenProvider.validateJwtToken(jwt)) {
                String username = tokenProvider.getUserNameFromJwtToken(jwt);
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                UsernamePasswordAuthenticationToken authentication
                        = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));

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

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

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

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

        return null;
    }
}

TokenProvider class

package com.example.RestApi.Configs;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.stream.Collectors;

@Component
public class TokenProvider {


    private String jwtSecret = "something";
    Logger logger = LoggerFactory.getLogger(TokenProvider.class);
    public String generateJwtToken(Authentication authentication) throws UnsupportedEncodingException {
        Date d = new Date();
        Date expiry = new Date(d.getTime() + 720000L);
        UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();

        final String authorities = userPrincipal.getAuthorities().stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.joining(","));

        String token = Jwts.builder()
                .setSubject((userPrincipal.getUsername()))
                .setIssuedAt(d)
                .claim("roles", authorities)
                .setExpiration(expiry)
                .signWith(SignatureAlgorithm.HS512, jwtSecret)
                .compact();
        return token;
    }

    public String getUserNameFromJwtToken(String token) {
        String userName = null;
        try {
            userName = Jwts.parser()
                    .setSigningKey(jwtSecret)
                    .parseClaimsJws(token)
                    .getBody().getSubject();
        } catch (Exception e) {
            System.out.println(e);
        }
        return userName;
    }

    public boolean validateJwtToken(String authToken) throws UnsupportedEncodingException {
        try {
            Jwts.parser().setSigningKey(jwtSecret)
                    .parseClaimsJws(authToken);
            return true;
        } catch (SignatureException e) {
            logger.debug("signature exception"+e);
        } catch (MalformedJwtException e) {
           logger.debug("token malformed"+e);

        } catch (ExpiredJwtException e) {
           logger.debug("token expired"+e);

        } catch (UnsupportedJwtException e) {
            logger.debug("unsupported"+e);

        } catch (IllegalArgumentException e) {
            logger.debug("Illegal"+e);

        }

        return false;
    }

}

Exception Facing

In validateToken() mehode I'm always getting this exception

Asim shahzad
  • 53
  • 1
  • 6
  • Seems its working as expected. As per screen shot you mentioned, token is already expired on "1/10" and you are trying it on "3/10". Can you regenerate new token and try again? – Shaunak Patel Oct 03 '18 at 16:25
  • @ShaunakPatel please consider the expiry date i have appended to the token in TokensProvider class and i didn't set "1/10" anywhere even after regenerating token i'm facing the same issue expiry date is always "1/10" – Asim shahzad Oct 03 '18 at 16:32
  • @Asimshahzad for me your code works fine as i checked, so check your system date or somewhere you are setting date in your application which might be generating old date. – kj007 Oct 04 '18 at 03:12
  • @kj007 there is no any other code script in my app which is dealing with token expiry time besides it. And my system time is also correct, whenever i run the code the expiry time is always 1/10. – Asim shahzad Oct 04 '18 at 11:31
  • how you are generating new token? – Shaunak Patel Oct 04 '18 at 11:32
  • @ShaunakPatel I'm using "JJWT" and generating token by myself through "Jwts.builder()" method, please check the method "genrateJwtToken()" in "TokenProvider" class in the code section. – Asim shahzad Oct 04 '18 at 11:37
  • @Asimshahzad can you check your system date match with current time ?? – kj007 Oct 04 '18 at 12:58
  • @Asimshahzad can you debug your code and check at token generation time what time your Date object return before adding expire time.. – kj007 Oct 04 '18 at 14:17
  • @kj007 yes system time is as it is as current time showing in the snap while debugging. – Asim shahzad Oct 04 '18 at 16:02
  • @Asimshahzad can you show me one token generated, share complete Bearer string..and if possible please share demo code on github, let me look at as I can see your code for generating token works fine as checked .. – kj007 Oct 04 '18 at 16:30
  • @kj007 yes sure here is the token "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhc2FkIiwiaWF0IjoxNTM4NjcyMjg2LCJyb2xlcyI6IlJPTEVfQURNSU4sUk9MRV9VU0VSLFJPTEVfQURNSVNTSU9OIiwiZXhwIjoxNTM4NjcyNDA2fQ.jjkeOgHHuFbQGklyEUC23Ta4apiJRBmYlZY1KeiWlY_Adqmz5aTyPMd82MtmR34TLFEF80xqg4A7UotlNHwZpw" – Asim shahzad Oct 04 '18 at 16:57
  • Your token is correctly generated as it says expire time Oct 04, 2018 22:30:06 IST – kj007 Oct 04 '18 at 17:09
  • Yes but while parsing that token on server side it is expired at 1/10. I am pushing my repo to github and will provide you link soon – Asim shahzad Oct 04 '18 at 17:15
  • @kj007 If you want to look into it then please consider this git repo. https://github.com/asim-ch/JWT-authentication-with-spring-boot – Asim shahzad Oct 04 '18 at 17:34
  • @Asimshahzad, I just tried to execute your code and its working as expected. Not sure why you are getting error. – Shaunak Patel Oct 04 '18 at 18:08
  • @Asimshahzad are you still facing issue after using system. Milliseconds, add five min more by multiplying 5 as might be because of two min window you are checking after two min, try and let me know as your code works fine for me. – kj007 Oct 04 '18 at 18:45
  • @ShaunakPatel still I'm getting that exception and I'm wondering that it is working in your case. What if i don't set any expiry date ? – Asim shahzad Oct 05 '18 at 02:02
  • @kj007 i tried everything i think problem is with my system but i don't know any, b/c system date is correct while generating token . – Asim shahzad Oct 05 '18 at 02:02
  • Try mvn clean install if Incase there is any conflict – kj007 Oct 05 '18 at 02:09
  • After Invalidating cache and restarting intellij it's working. Thanks guyz for your time. – Asim shahzad Oct 05 '18 at 02:21
  • @Asimshahzad great, I have posted answer – kj007 Oct 05 '18 at 02:41

2 Answers2

1

Your code seems to be working fine as tested by me too.

So try of couple of things

  1. Do clean install by command line mvn clean install

  2. Remove m2 repository and then again import dependencies

  3. Try removing cache and restart IDE and system

kj007
  • 6,073
  • 4
  • 29
  • 47
0

I had the same issue. Tried @kj007 answer. However it didn't work for me.

In my case it was an Insomnia bug. After restarting it, everything was ok. I deem somehow it was sending an old token.

valijon
  • 1,304
  • 2
  • 20
  • 35