You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/05/30 14:28:29 UTC

[2/2] syncope git commit: [SYNCOPE-1100] Providing JWT expire as HTTP header in response to login + adding support for that with SAML 2.0 SP Agent

[SYNCOPE-1100] Providing JWT expire as HTTP header in response to login + adding support for that with SAML 2.0 SP Agent


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/03cb2f01
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/03cb2f01
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/03cb2f01

Branch: refs/heads/master
Commit: 03cb2f012124a40a6f9ef4b5861beb32a2798848
Parents: d40aafe
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue May 30 16:28:07 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue May 30 16:28:17 2017 +0200

----------------------------------------------------------------------
 .../syncope/common/rest/api/RESTHeaders.java     |  2 ++
 .../syncope/core/logic/AccessTokenLogic.java     |  6 ++++--
 .../api/data/AccessTokenDataBinder.java          |  5 +++--
 .../java/data/AccessTokenDataBinderImpl.java     | 19 +++++++++++++------
 .../rest/cxf/service/AccessTokenServiceImpl.java | 13 +++++++++++--
 .../ext/saml2lsp/agent/AssertionConsumer.java    |  1 +
 .../syncope/ext/saml2lsp/agent/Constants.java    |  2 ++
 .../common/lib/to/SAML2LoginResponseTO.java      | 10 ++++++++++
 .../apache/syncope/core/logic/SAML2SPLogic.java  |  5 ++++-
 9 files changed, 50 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
index 0c54116..2a61321 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
@@ -27,6 +27,8 @@ public final class RESTHeaders {
 
     public static final String TOKEN = "X-Syncope-Token";
 
+    public static final String TOKEN_EXPIRE = "X-Syncope-Token-Expire";
+
     public static final String OWNED_ENTITLEMENTS = "X-Syncope-Entitlements";
 
     public static final String RESOURCE_KEY = "X-Syncope-Key";

http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
index ece23d0..c495392 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AccessTokenLogic.java
@@ -21,10 +21,12 @@ package org.apache.syncope.core.logic;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import javax.annotation.Resource;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.to.AccessTokenTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
@@ -50,7 +52,7 @@ public class AccessTokenLogic extends AbstractTransactionalLogic<AccessTokenTO>
     private AccessTokenDAO accessTokenDAO;
 
     @PreAuthorize("isAuthenticated()")
-    public String login() {
+    public Pair<String, Date> login() {
         if (anonymousUser.equals(AuthContextUtils.getUsername())) {
             throw new IllegalArgumentException(anonymousUser + " cannot be granted for an access token");
         }
@@ -59,7 +61,7 @@ public class AccessTokenLogic extends AbstractTransactionalLogic<AccessTokenTO>
     }
 
     @PreAuthorize("isAuthenticated()")
-    public String refresh() {
+    public Pair<String, Date> refresh() {
         AccessToken accessToken = accessTokenDAO.findByOwner(AuthContextUtils.getUsername());
         if (accessToken == null) {
             throw new NotFoundException("AccessToken for " + AuthContextUtils.getUsername());

http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java
index b24137f..be51926 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AccessTokenDataBinder.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.provisioning.api.data;
 
 import java.util.Date;
 import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.commons.lang3.tuple.Triple;
 import org.apache.syncope.common.lib.to.AccessTokenTO;
 import org.apache.syncope.core.persistence.api.entity.AccessToken;
@@ -28,9 +29,9 @@ public interface AccessTokenDataBinder {
 
     Triple<String, String, Date> generateJWT(String subject, int duration, Map<String, Object> claims);
 
-    String create(String subject, Map<String, Object> claims, boolean replaceExisting);
+    Pair<String, Date> create(String subject, Map<String, Object> claims, boolean replaceExisting);
 
-    String update(AccessToken accessToken);
+    Pair<String, Date> update(AccessToken accessToken);
 
     AccessTokenTO getAccessTokenTO(AccessToken accessToken);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
----------------------------------------------------------------------
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 6bca7e0..5159733 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
@@ -24,6 +24,7 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.Map;
 import javax.annotation.Resource;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.commons.lang3.tuple.Triple;
 import org.apache.cxf.rs.security.jose.common.JoseType;
 import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
@@ -110,12 +111,16 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
     }
 
     @Override
-    public String create(final String subject, final Map<String, Object> claims, final boolean replaceExisting) {
+    public Pair<String, Date> create(
+            final String subject, final Map<String, Object> claims, final boolean replaceExisting) {
+
         String body = null;
+        Date expiryTime = null;
 
         AccessToken existing = accessTokenDAO.findByOwner(subject);
         if (existing != null) {
             body = existing.getBody();
+            expiryTime = existing.getExpiryTime();
         }
 
         if (replaceExisting || body == null) {
@@ -125,11 +130,12 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
                     claims);
 
             body = created.getMiddle();
+            expiryTime = created.getRight();
 
             AccessToken accessToken = entityFactory.newEntity(AccessToken.class);
             accessToken.setKey(created.getLeft());
             accessToken.setBody(body);
-            accessToken.setExpiryTime(created.getRight());
+            accessToken.setExpiryTime(expiryTime);
             accessToken.setOwner(subject);
 
             if (!adminUser.equals(accessToken.getOwner())) {
@@ -149,11 +155,11 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
             accessTokenDAO.delete(existing);
         }
 
-        return body;
+        return Pair.of(body, expiryTime);
     }
 
     @Override
-    public String update(final AccessToken accessToken) {
+    public Pair<String, Date> update(final AccessToken accessToken) {
         JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(accessToken.getBody());
 
         Date now = new Date();
@@ -167,9 +173,10 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
         JwsJwtCompactProducer producer = new JwsJwtCompactProducer(token);
 
         String body = producer.signWith(jwsSignatureProvider);
+        Date expiryTime = expiry.getTime();
 
         accessToken.setBody(body);
-        accessToken.setExpiryTime(expiry.getTime());
+        accessToken.setExpiryTime(expiryTime);
 
         if (!adminUser.equals(accessToken.getOwner())) {
             try {
@@ -183,7 +190,7 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
 
         accessTokenDAO.save(accessToken);
 
-        return body;
+        return Pair.of(body, expiryTime);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java
index f5859db..54db9cc 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AccessTokenServiceImpl.java
@@ -18,7 +18,10 @@
  */
 package org.apache.syncope.core.rest.cxf.service;
 
+import java.util.Date;
 import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.to.AccessTokenTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -36,15 +39,21 @@ public class AccessTokenServiceImpl extends AbstractServiceImpl implements Acces
 
     @Override
     public Response login() {
+        Pair<String, Date> login = logic.login();
         return Response.noContent().
-                header(RESTHeaders.TOKEN, logic.login()).
+                header(RESTHeaders.TOKEN, login.getLeft()).
+                header(RESTHeaders.TOKEN_EXPIRE,
+                        DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.format(login.getRight())).
                 build();
     }
 
     @Override
     public Response refresh() {
+        Pair<String, Date> refresh = logic.refresh();
         return Response.noContent().
-                header(RESTHeaders.TOKEN, logic.refresh()).
+                header(RESTHeaders.TOKEN, refresh.getLeft()).
+                header(RESTHeaders.TOKEN_EXPIRE,
+                        DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.format(refresh.getRight())).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
index 6407b4d..698aa7f 100644
--- a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
+++ b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
@@ -45,6 +45,7 @@ public class AssertionConsumer extends AbstractSAML2SPServlet {
                     validateLoginResponse(extract(request.getInputStream()));
 
             request.getSession(true).setAttribute(Constants.SAML2SPJWT, responseTO.getAccessToken());
+            request.getSession(true).setAttribute(Constants.SAML2SPJWT_EXPIRE, responseTO.getAccessTokenExpiryTime());
 
             String successURL = getServletContext().getInitParameter(Constants.CONTEXT_PARAM_LOGIN_SUCCESS_URL);
             if (successURL == null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Constants.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Constants.java b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Constants.java
index 619e4b8..b7da815 100644
--- a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Constants.java
+++ b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Constants.java
@@ -36,6 +36,8 @@ public final class Constants {
 
     public static final String SAML2SPJWT = "saml2sp.jwt";
 
+    public static final String SAML2SPJWT_EXPIRE = "saml2sp.jwt.expire";
+
     private Constants() {
         // private constructor for static utility class
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
index 941d7c5..f905035 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
@@ -44,6 +44,8 @@ public class SAML2LoginResponseTO extends AbstractBaseBean {
 
     private String accessToken;
 
+    private Date accessTokenExpiryTime;
+
     private String username;
 
     private final Set<AttrTO> attrs = new HashSet<>();
@@ -106,6 +108,14 @@ public class SAML2LoginResponseTO extends AbstractBaseBean {
         this.accessToken = accessToken;
     }
 
+    public Date getAccessTokenExpiryTime() {
+        return accessTokenExpiryTime;
+    }
+
+    public void setAccessTokenExpiryTime(final Date accessTokenExpiryTime) {
+        this.accessTokenExpiryTime = accessTokenExpiryTime;
+    }
+
     public String getUsername() {
         return username;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/03cb2f01/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
index 9835061..e5c444c 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
@@ -33,6 +33,7 @@ import java.util.List;
 import java.util.Map;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.commons.lang3.tuple.Triple;
 import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
@@ -530,7 +531,9 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
         claims.put(JWT_CLAIM_NAMEID_FORMAT, nameID.getFormat());
         claims.put(JWT_CLAIM_NAMEID_VALUE, nameID.getValue());
         claims.put(JWT_CLAIM_SESSIONINDEX, responseTO.getSessionIndex());
-        responseTO.setAccessToken(accessTokenDataBinder.create(responseTO.getUsername(), claims, true));
+        Pair<String, Date> accessTokenInfo = accessTokenDataBinder.create(responseTO.getUsername(), claims, true);
+        responseTO.setAccessToken(accessTokenInfo.getLeft());
+        responseTO.setAccessTokenExpiryTime(accessTokenInfo.getRight());
 
         return responseTO;
     }