Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 13D55200D3C for ; Tue, 14 Nov 2017 18:55:33 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 12749160BD7; Tue, 14 Nov 2017 17:55:33 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 0C98C160C08 for ; Tue, 14 Nov 2017 18:55:31 +0100 (CET) Received: (qmail 96127 invoked by uid 500); 14 Nov 2017 17:55:31 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 96049 invoked by uid 99); 14 Nov 2017 17:55:31 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 14 Nov 2017 17:55:31 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 8BFDA81AD7; Tue, 14 Nov 2017 17:55:30 +0000 (UTC) Date: Tue, 14 Nov 2017 17:55:33 +0000 To: "commits@cxf.apache.org" Subject: [cxf-fediz] 03/03: id_token exp should be computed at creation time MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit From: gonzalad@apache.org In-Reply-To: <151068213044.21688.9636001403956565745@gitbox.apache.org> References: <151068213044.21688.9636001403956565745@gitbox.apache.org> X-Git-Host: gitbox.apache.org X-Git-Repo: cxf-fediz X-Git-Refname: refs/heads/1.4.x-fixes X-Git-Reftype: branch X-Git-Rev: c0631b318a180fe86a3410f0445f5caf4189fd5c X-Git-NotificationType: diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated Message-Id: <20171114175530.8BFDA81AD7@gitbox.apache.org> archived-at: Tue, 14 Nov 2017 17:55:33 -0000 This is an automated email from the ASF dual-hosted git repository. gonzalad pushed a commit to branch 1.4.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf-fediz.git commit c0631b318a180fe86a3410f0445f5caf4189fd5c Author: gonzalad 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 e8ad831..dae3a10 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 supportedClaims = Collections.emptyMap(); + private long timeToLive; @Override public OidcUserSubject createUserSubject(MessageContext mc, - MultivaluedMap params) throws OAuthServiceException { + MultivaluedMap 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 @@ -74,13 +77,8 @@ public class FedizSubjectCreator implements SubjectCreator { 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. @@ -89,47 +87,26 @@ public class FedizSubjectCreator implements SubjectCreator { return oidcSub; } - private IdToken convertToIdToken(MessageContext mc, - Element samlToken, - String subjectName, - String subjectId, - ClaimCollection claims, - List roles, - MultivaluedMap params) { + private IdToken convertToIdToken(MessageContext mc, Element samlToken, String subjectName, String subjectId, + ClaimCollection claims, List roles, + MultivaluedMap 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("/")) { @@ -156,23 +133,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 requestedClaimsList = new ArrayList(); - //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 @@ -193,16 +174,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()); } } @@ -211,29 +192,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 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) { @@ -247,16 +227,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: @@ -272,4 +246,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" .