6

The problem is that my application throws an exception when the token expires and I can't catch that exception. I want to catch that exception and do another thing. Tried commenting exception statement on catch block but no progress.

Exception:

 **03-Mar-2018 18:32:16.941 SEVERE [http-nio-1234-exec-26]                          org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service()
 for servlet [Jersey Web Application] in context with path [/uis] threw
 exception [io.jsonwebtoken.ExpiredJwtException: JWT expired at
 2018-03-03T18:32:03Z. Current time: 2018-03-03T18:32:16Z, a difference
 of 13940 milliseconds.  Allowed clock skew: 0 milliseconds.] with root
 cause  io.jsonwebtoken.ExpiredJwtException: JWT expired at
 2018-03-03T18:32:03Z. Current time: 2018-03-03T18:32:16Z, a difference
 of 13940 milliseconds.  Allowed clock skew: 0 milliseconds.    at
 io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:385)
    at
 io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481)
    at
 io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:541)
    at az.naxtel.java.JWTController.isValid(JWTController.java:53)  at
 az.naxtel.java.JWTController.getManagerFromToken(JWTController.java:37)
    at
 az.naxtel.api.cc.resource.RedmineJournalResource.getJournalsCount(RedmineJournalResource.java:59)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at
 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)     at
 org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:76)
    at
 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:148)
    at
 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:191)
    at
 org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
    at
 org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
    at
 org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
    at
 org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
    at
 org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
    at
 org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)     at
 org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)   at
 org.glassfish.jersey.internal.Errors.process(Errors.java:316)  at
 org.glassfish.jersey.internal.Errors.process(Errors.java:298)  at
 org.glassfish.jersey.internal.Errors.process(Errors.java:268)  at
 org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
    at
 org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
    at
 org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
    at
 org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
    at
 org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
    at
 org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
    at
 org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
    at
 org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
    at
 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at
 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at
 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    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:198)
    at
 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at
 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at
 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at
 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at
 org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
    at
 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at
 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at
 org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
    at
 org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at
 org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
    at
 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
    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)**

Checking token:

    private boolean isValid(String token) {
    boolean validation = false;
    try {
        Jwts.parser().setSigningKey(PRIVATE_KEY).parseClaimsJws(token).getBody().getSubject();
        validation = true;
    } catch (SignatureException e) {
        Logger.getLogger(JWTController.class.getName()).log(Level.ERROR, e);
    }
    return validation;
}
Nikos Hidalgo
  • 3,666
  • 9
  • 25
  • 39
user8920693
  • 85
  • 1
  • 1
  • 9

2 Answers2

11

It's because you are not catching the relevant exception.

Change your code by adding the following catch (ExpiredJwtException e) declaration:

Try this:

try {
    Jwts.parser().setSigningKey(PRIVATE_KEY).parseClaimsJws(token).getBody().getSubject();
    validation = true;
} catch (ExpiredJwtException e) {
    System.out.println(" Token expired ");
} catch (SignatureException e) {
    Logger.getLogger(JWTController.class.getName()).log(Level.ERROR, e);
} catch(Exception e){
    System.out.println(" Some other exception in JWT parsing ");
}
tryingToLearn
  • 10,691
  • 12
  • 80
  • 114
  • 1
    Still no progress. It throws exception even i'm commenting Logger on expiredjwtexception block. – user8920693 Mar 03 '18 at 15:06
  • 2
    Have you tried putting a `println` instead of logger? Or have you tried by putting a breakpoint? – tryingToLearn Mar 03 '18 at 15:09
  • Yeah, it worked) Why is throwing when I am logging exception? It's very interesting. And thank you very much! – user8920693 Mar 03 '18 at 15:21
  • 1
    Your code had 2 problems. One of them, described in the question, was due to non-existence of `catch (ExpiredJwtException e)`. 2nd problem is that of Logger that you are using. To debug that more info will be needed. You can post it as a separate question. – tryingToLearn Mar 03 '18 at 15:25
  • Before I have tried catching main Exception but again problem hadn't solve. Thanks – user8920693 Mar 03 '18 at 15:27
  • If you post the question describing issues with your `Logger`, feel free to share the link in comments. – tryingToLearn Mar 03 '18 at 15:31
2

Please read this: https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4

The "exp" (expiration time) claim identifies the expiration time on
or after which the JWT MUST NOT be accepted for processing. The
processing of the "exp" claim requires that the current date/time
MUST be before the expiration date/time listed in the "exp" claim.

Therefore, it throws the exception, as it should!

If you want to extend it's expiration date, IT WILL THROW THE EXCEPTION!

I would suggest you implement authorization with the refresh and access token flow.

I suggest you take a look at @doctore's answer here: How can I refresh tokens in Spring security


Manage access and refresh tokens User logins into the application (including username and password)

Your backend application returns any required credentials information and:

2.1 Access JWT token with an expired time usually "low" (15, 30 minutes, etc).

2.2 Refresh JWT token with an expired time greater than access one.

From now, your frontend application will use access token in the Authorization header for every request.

When backend returns 401, the frontend application will try to use refresh token in the header (using an specific endpoint) to get new a new pair of access and refresh token!!!

Implementation flow => Refresh token flow


For reference: Parser throws exception when token is expired

Community
  • 1
  • 1
Alexandros Kourtis
  • 539
  • 2
  • 6
  • 20