5

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;
}
4

2 回答 2

10

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 ");
}
于 2018-03-03T15:00:23.517 回答
0

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

于 2020-08-21T15:35:37.650 回答