This is an automated email from the ASF dual-hosted git repository. ilgrosso pushed a commit to branch 2_0_X in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/2_0_X by this push: new db5a002 [SYNCOPE-1420] Replacing expired access tokens upon login db5a002 is described below commit db5a0020103cf2aee42e360c59f3ca4b57549d4a Author: Francesco Chicchiriccò <ilgro...@apache.org> AuthorDate: Fri Dec 21 11:55:16 2018 +0100 [SYNCOPE-1420] Replacing expired access tokens upon login --- .../java/data/AccessTokenDataBinderImpl.java | 4 +-- .../org/apache/syncope/fit/core/JWTITCase.java | 38 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java index 327b396..45492cf 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java @@ -137,8 +137,8 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder { accessToken.setKey(UUID_GENERATOR.generate().toString()); accessToken = replace(subject, claims, authorities, accessToken); - } else if (replace) { - // AccessToken found, but replace requested: update existing + } else if (replace || accessToken.getExpiryTime() == null || accessToken.getExpiryTime().before(new Date())) { + // AccessToken found, but either replace was requested or it is expired: update existing accessToken = replace(subject, claims, authorities, accessToken); } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/JWTITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/JWTITCase.java index 0720961..a1dbf38 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/JWTITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/JWTITCase.java @@ -20,6 +20,7 @@ package org.apache.syncope.fit.core; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -47,6 +48,7 @@ import org.apache.cxf.rs.security.jose.jws.NoneJwsSignatureProvider; import org.apache.cxf.rs.security.jose.jwt.JwtClaims; import org.apache.cxf.rs.security.jose.jwt.JwtToken; import org.apache.syncope.client.lib.SyncopeClient; +import org.apache.syncope.common.lib.to.AttrTO; import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.rest.api.RESTHeaders; import org.apache.syncope.common.rest.api.service.AccessTokenService; @@ -551,4 +553,40 @@ public class JWTITCase extends AbstractITCase { // expected } } + + @Test + public void issueSYNCOPE1420() { + AttrTO orig = configurationService.get("jwt.lifetime.minutes"); + try { + // set for immediate JWT expiration + configurationService.set(new AttrTO.Builder().schema("jwt.lifetime.minutes").value("0").build()); + + UserTO user = UserITCase.getUniqueSampleTO("syncope...@syncope.apache.org"); + user = createUser(user).getEntity(); + assertNotNull(user); + + // login, get JWT with expiryTime + String jwt = clientFactory.create(user.getUsername(), "password123").getJWT(); + + JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(jwt); + assertTrue(consumer.verifySignatureWith(jwsSignatureVerifier)); + Long expiryTime = consumer.getJwtClaims().getExpiryTime(); + assertNotNull(expiryTime); + + // wait for 1 sec, check that JWT is effectively expired + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + // ignore + } + assertTrue(expiryTime < System.currentTimeMillis()); + + // login again, get new JWT + // (even if ExpiredAccessTokenCleanup did not run yet, as it is scheduled every 5 minutes) + String newJWT = clientFactory.create(user.getUsername(), "password123").getJWT(); + assertNotEquals(jwt, newJWT); + } finally { + configurationService.set(orig); + } + } }