cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gonza...@apache.org
Subject [cxf-fediz] branch master updated: id_token exp should be computed at creation time
Date Tue, 14 Nov 2017 17:39:43 GMT
This is an automated email from the ASF dual-hosted git repository.

gonzalad pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf-fediz.git


The following commit(s) were added to refs/heads/master by this push:
     new fa5902c  id_token exp should be computed at creation time
fa5902c is described below

commit fa5902c218b9668c92a17be2474473e8f026dc63
Author: gonzalad <adr_gonzalez@yahoo.fr>
AuthorDate: Tue Nov 14 18:39:41 2017 +0100

    id_token exp should be computed at creation time
    
    id_token expiry claim is now computed at id_token generation time.
    
    It was previously computed from SAML token expiry.
    Since SAML token is generated once per OIDC httpSession
    and can be reused for generating multiple id_token, it introduced
    some issues where the id_token is generated with an already expired claim.
    
    We now compute the exp claim as :
    
     * use timeToLive attribute of FedizSubjectCreator if it is strictly positive.
     * use maxInactiveInterval from httpSession if it is strictly positive.
     * otherwise use the default of 1 hour.
---
 .../fediz/service/oidc/FedizSubjectCreator.java    | 124 ++++++++++-----------
 1 file changed, 56 insertions(+), 68 deletions(-)

diff --git a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/FedizSubjectCreator.java
b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/FedizSubjectCreator.java
index 08e63dc..7f86a80 100644
--- a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/FedizSubjectCreator.java
+++ b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/FedizSubjectCreator.java
@@ -26,6 +26,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import javax.servlet.http.HttpSession;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.UriBuilder;
 
@@ -51,21 +52,23 @@ import org.opensaml.saml.saml2.core.Issuer;
 
 
 public class FedizSubjectCreator implements SubjectCreator {
+
+    private static final long DEFAULT_TIME_TO_LIVE = 3600L;
     private static final String ROLES_SCOPE = "roles";
     private boolean stripPathFromIssuerUri;
     private String issuer;
-    private long defaultTimeToLive = 3600L;
     private Map<String, String> supportedClaims = Collections.emptyMap();
+    private long timeToLive;
 
     @Override
     public OidcUserSubject createUserSubject(MessageContext mc,
-                                         MultivaluedMap<String, String> params) throws
OAuthServiceException {
+                                             MultivaluedMap<String, String> params)
throws OAuthServiceException {
         Principal principal = mc.getSecurityContext().getUserPrincipal();
 
         if (!(principal instanceof FedizPrincipal)) {
             throw new OAuthServiceException("Unsupported Principal");
         }
-        FedizPrincipal fedizPrincipal = (FedizPrincipal)principal;
+        FedizPrincipal fedizPrincipal = (FedizPrincipal) principal;
 
         // In the future FedizPrincipal will likely have JWT claims already prepared,
         // with IdToken being initialized here from those claims
@@ -75,13 +78,8 @@ public class FedizSubjectCreator implements SubjectCreator {
         // REVISIT: use fedizPrincipal.getId() to guarantee the uniqueness once FEDIZ-207
is resolved
         oidcSub.setId(fedizPrincipal.getName());
 
-        IdToken idToken = convertToIdToken(mc,
-                                           fedizPrincipal.getLoginToken(),
-                                           oidcSub.getLogin(),
-                                           oidcSub.getId(),
-                                           fedizPrincipal.getClaims(),
-                                           fedizPrincipal.getRoleClaims(),
-                                           params);
+        IdToken idToken = convertToIdToken(mc, fedizPrincipal.getLoginToken(), oidcSub.getLogin(),
oidcSub.getId(),
+                fedizPrincipal.getClaims(), fedizPrincipal.getRoleClaims(), params);
         oidcSub.setIdToken(idToken);
         oidcSub.setRoles(fedizPrincipal.getRoleClaims());
         // UserInfo can be populated and set on OidcUserSubject too.
@@ -90,47 +88,26 @@ public class FedizSubjectCreator implements SubjectCreator {
         return oidcSub;
     }
 
-    private IdToken convertToIdToken(MessageContext mc,
-            Element samlToken,
-            String subjectName,
-            String subjectId,
-            ClaimCollection claims,
-            List<String> roles,
-            MultivaluedMap<String, String> params) {
+    private IdToken convertToIdToken(MessageContext mc, Element samlToken, String subjectName,
String subjectId,
+                                     ClaimCollection claims, List<String> roles,
+                                     MultivaluedMap<String, String> params) {
         // The current SAML Assertion represents an authentication record.
         // It has to be translated into IdToken (JWT) so that it can be returned
         // to client applications participating in various OIDC flows.
 
         IdToken idToken = new IdToken();
 
-        //TODO: make the mapping between the subject name and IdToken claim configurable
+        // TODO: make the mapping between the subject name and IdToken claim configurable
         idToken.setPreferredUserName(subjectName);
         idToken.setSubject(subjectId);
 
         Assertion saml2Assertion = getSaml2Assertion(samlToken);
-        if (saml2Assertion != null) {
-            // issueInstant
-            DateTime issueInstant = saml2Assertion.getIssueInstant();
-            if (issueInstant != null) {
-                idToken.setIssuedAt(issueInstant.getMillis() / 1000);
-            }
-
-            // expiryTime
-            if (saml2Assertion.getConditions() != null) {
-                DateTime expires = saml2Assertion.getConditions().getNotOnOrAfter();
-                if (expires != null) {
-                    idToken.setExpiryTime(expires.getMillis() / 1000);
-                }
-            }
-
-            // authInstant
-            if (!saml2Assertion.getAuthnStatements().isEmpty()) {
-                DateTime authInstant =
-                saml2Assertion.getAuthnStatements().get(0).getAuthnInstant();
-                idToken.setAuthenticationTime(authInstant.getMillis() / 1000L);
-            }
+        // authInstant
+        if (saml2Assertion != null && !saml2Assertion.getAuthnStatements().isEmpty())
{
+            DateTime authInstant = saml2Assertion.getAuthnStatements().get(0).getAuthnInstant();
+            idToken.setAuthenticationTime(authInstant.getMillis() / 1000L);
         }
-        // Check if default issuer, issuedAt and expiryTime values have to be set
+        // Check if default issuer, issuedAt values have to be set
         if (issuer != null) {
             String realIssuer = null;
             if (issuer.startsWith("/")) {
@@ -157,23 +134,27 @@ public class FedizSubjectCreator implements SubjectCreator {
             }
         }
 
+        // Compute exp claim
         long currentTimeInSecs = System.currentTimeMillis() / 1000;
-        if (idToken.getIssuedAt() == null) {
-            idToken.setIssuedAt(currentTimeInSecs);
-        }
-        if (idToken.getExpiryTime() == null) {
-            idToken.setExpiryTime(currentTimeInSecs + defaultTimeToLive);
+        idToken.setIssuedAt(currentTimeInSecs);
+        HttpSession httpSession = mc.getHttpServletRequest().getSession(false);
+        if (timeToLive > 0) {
+            idToken.setExpiryTime(timeToLive);
+        } else if (httpSession != null && httpSession.getMaxInactiveInterval() >
0) {
+            idToken.setExpiryTime(currentTimeInSecs + httpSession.getMaxInactiveInterval());
+        } else {
+            idToken.setExpiryTime(currentTimeInSecs + DEFAULT_TIME_TO_LIVE);
         }
 
         List<String> requestedClaimsList = new ArrayList<String>();
-        //Derive claims from scope
+        // Derive claims from scope
         String requestedScope = params.getFirst(OAuthConstants.SCOPE);
         if (requestedScope != null && !requestedScope.isEmpty()) {
             String[] scopes = requestedScope.split(" ");
-            //TODO: Note that if the consent screen enabled then it is feasible
+            // TODO: Note that if the consent screen enabled then it is feasible
             // that the claims added in this code after mapping the scopes to claims
             // may need to be removed if the user disapproves the related scope
-            
+
             // standard scope to claims mapping:
             requestedClaimsList.addAll(OidcUtils.getScopeClaims(scopes));
             // custom scopes to claims mapping
@@ -194,16 +175,16 @@ public class FedizSubjectCreator implements SubjectCreator {
                     continue;
                 }
                 if (ClaimTypes.FIRSTNAME.equals(c.getClaimType())) {
-                    idToken.setGivenName((String)c.getValue());
-                    firstName = (String)c.getValue();
+                    idToken.setGivenName((String) c.getValue());
+                    firstName = (String) c.getValue();
                 } else if (ClaimTypes.LASTNAME.equals(c.getClaimType())) {
-                    idToken.setFamilyName((String)c.getValue());
-                    lastName = (String)c.getValue();
+                    idToken.setFamilyName((String) c.getValue());
+                    lastName = (String) c.getValue();
                 } else if (ClaimTypes.EMAILADDRESS.equals(c.getClaimType())) {
-                    idToken.setEmail((String)c.getValue());
+                    idToken.setEmail((String) c.getValue());
                 } else if (supportedClaims.containsKey(c.getClaimType().toString())
-                    && requestedClaimsList.contains(supportedClaims.get(c.getClaimType().toString())))
{
-                    idToken.setClaim(supportedClaims.get(c.getClaimType().toString()), (String)c.getValue());
+                        && requestedClaimsList.contains(supportedClaims.get(c.getClaimType().toString())))
{
+                    idToken.setClaim(supportedClaims.get(c.getClaimType().toString()), (String)
c.getValue());
                 }
 
             }
@@ -212,29 +193,28 @@ public class FedizSubjectCreator implements SubjectCreator {
             }
         }
 
-        if (roles != null && !roles.isEmpty() 
-            && supportedClaims.containsKey(FedizConstants.DEFAULT_ROLE_URI.toString()))
{
-            
+        if (roles != null && !roles.isEmpty()
+                && supportedClaims.containsKey(FedizConstants.DEFAULT_ROLE_URI.toString()))
{
+
             String roleClaimName = supportedClaims.get(FedizConstants.DEFAULT_ROLE_URI.toString());
             if (requestedClaimsList.contains(roleClaimName)) {
                 idToken.setClaim(roleClaimName, roles);
-            }            
+            }
         }
 
         return idToken;
     }
 
-
     private List<String> getCustomScopeClaims(String[] scopes) {
         // For now the only custom scope (to claims) mapping Fediz supports is
         // roles where the scope name is expected to be 'roles' and the role name must be
configured
         String roleClaimName = supportedClaims.get(FedizConstants.DEFAULT_ROLE_URI.toString());
         if (roleClaimName != null && Arrays.asList(scopes).contains(ROLES_SCOPE))
{
-            return Collections.singletonList(roleClaimName);    
+            return Collections.singletonList(roleClaimName);
         } else {
             return Collections.emptyList();
         }
-        
+
     }
 
     private Assertion getSaml2Assertion(Element samlToken) {
@@ -248,16 +228,10 @@ public class FedizSubjectCreator implements SubjectCreator {
 
     }
 
-
     public void setIdTokenIssuer(String idTokenIssuer) {
         this.issuer = idTokenIssuer;
     }
 
-
-    public void setIdTokenTimeToLive(long idTokenTimeToLive) {
-        this.defaultTimeToLive = idTokenTimeToLive;
-    }
-
     /**
      * Set a map of supported claims. The map is from a SAML ClaimType URI String to a claim
value that is
      * sent in the claims parameter. So for example:
@@ -273,4 +247,18 @@ public class FedizSubjectCreator implements SubjectCreator {
         this.stripPathFromIssuerUri = stripPathFromIssuerUri;
     }
 
+    /**
+     * Time to live in seconds (used for id_token exp claim).
+     *
+     * If this value is set and strictly positive, then the generated
+     * id_token will use this value for the exp claim.
+     *
+     * Otherwise, it will use maxInactiveInterval of httpSession, and
+     * if this later is not strictly positive, it will be 1 hour by default.
+     *
+     * @param timeToLive time to live in seconds of the id_token
+     */
+    public void setTimeToLive(long timeToLive) {
+        this.timeToLive = timeToLive;
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
['"commits@cxf.apache.org" <commits@cxf.apache.org>'].

Mime
View raw message