[java-oidc-common] 02/03: Removed the deprecated AuthenticationTimeClaimsValidator class + references.

Henri Mikkonen henri.mikkonen at iki.fi
Fri Sep 8 10:56:58 UTC 2023


This is an automated email from the git hooks/post-receive script.

hjmikkon pushed a commit to branch main
in repository java-oidc-common.

View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=088a7de402d76fbed8bebe6fd65a36bca13a843e

commit 088a7de402d76fbed8bebe6fd65a36bca13a843e
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Sep 8 13:49:23 2023 +0300

    Removed the deprecated AuthenticationTimeClaimsValidator class + references.
---
 .../impl/AuthenticationTimeClaimsValidator.java    | 244 ---------------------
 .../AuthenticationTimeClaimsValidatorTest.java     | 202 -----------------
 .../impl/ChainingJWTClaimsValidatorTest.java       |  27 ---
 3 files changed, 473 deletions(-)

diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AuthenticationTimeClaimsValidator.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AuthenticationTimeClaimsValidator.java
deleted file mode 100644
index d78e843..0000000
--- a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AuthenticationTimeClaimsValidator.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package net.shibboleth.oidc.security.jwt.claims.impl;
-
-import java.text.ParseException;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.Date;
-import java.util.function.Function;
-import java.util.function.Predicate;
-
-import javax.annotation.Nonnull;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Predicates;
-import com.nimbusds.jwt.JWTClaimsSet;
-
-import net.shibboleth.oidc.jwt.claims.AbstractClaimsValidator;
-import net.shibboleth.oidc.jwt.claims.JWTValidationException;
-import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.logic.FunctionSupport;
-
-/**
- * Verifies the auth_time (when the End-User authentication took place):
- * <ol>
- * <li>If the authnLifetimeLookup returns 0 seconds (e.g. max_age=0), assume the 'forced authentication' semantic, and 
- * check the auth_time is after the authentication request time.</li>
- * <li>Or, if the authnLifetimeLookup returns a value >0, check the authentication occurred within a valid expiration
- * window.</li>
- * </ol>
- * 
- * <p>A predicate determines if the auth_time was requested e.g. was explicitly requested, or the max_age
- * claim was set. Defaults to true.</p>
- */
- at ThreadSafeAfterInit
-public class AuthenticationTimeClaimsValidator extends AbstractClaimsValidator {
-    
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(AuthenticationTimeClaimsValidator.class);
-    
-    /** 
-     * Lookup strategy to find the amount of time for which a token is valid 
-     * after if it was first issued. (Default value: 60 seconds) 
-     */
-    @Nonnull private Function<ProfileRequestContext, Duration> authnLifetimeLookupStrategy;
-    
-    /** 
-     * Lookup strategy to find the time at which the authentication request was made.
-     * Defaults to now minus the clockskew.
-     */
-    @Nonnull private Function<ProfileRequestContext, Instant> authnRequestTimeLookupStrategy;
-    
-    /** 
-     * Positive clock skew adjustment to consider when checking auth_time is not in the future 
-     * or has expired. (Default value: 60 seconds). 
-     */
-    @Nonnull private Duration clockSkew;
-    
-    /**
-     *  Has the auth_time been requested, either explicitly or from the max_age parameter?
-     *  Defaults to true. 
-     */ 
-    @Nonnull private Predicate<ProfileRequestContext> requested;
-    
-    /** Constructor.*/
-    public AuthenticationTimeClaimsValidator() {
-        authnLifetimeLookupStrategy = prc ->  Duration.ofSeconds(60);
-        clockSkew = Duration.ofSeconds(60);
-        authnRequestTimeLookupStrategy = prc -> Instant.now().minus(clockSkew);
-        requested = Predicates.alwaysTrue();
-    }
-    
-    /**
-     * Set the clock skew.
-     * 
-     * @param skew clock skew to set
-     */
-    public void setClockSkew(@Nonnull final Duration skew) {  
-        ifInitializedThrowUnmodifiabledComponentException();
-        
-        clockSkew = Constraint.isNotNull(skew, "Clock skew cannot be null");
-    }
-    
-    /**
-     * Set the lookup strategy to find out when the authentication request (if any) was made.
-     * 
-     * @param strategy the strategy
-     * 
-     * @since 2.2.0
-     */
-    public void setAuthnRequestTimeLookupStrategy(
-            final Function<ProfileRequestContext, Instant> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
-        ifDestroyedThrowDestroyedComponentException();
-
-        authnRequestTimeLookupStrategy = Constraint.isNotNull(strategy,
-                "authnRequestTimeLookupStrategy can not be null");
-    }
-
-    
-    /**
-     * Has the auth_time been request e.g. explicitly, or by using the max_age parameter.
-     * @deprecated use the activation condition in the base class instead.
-     * 
-     * @param isRequested has auth_time been requested.
-     */
-    @Deprecated(forRemoval = true, since = "2.2.0")
-    public void setRequested(final Predicate<ProfileRequestContext> isRequested) {
-        ifInitializedThrowUnmodifiabledComponentException();
-        
-        requested = isRequested;
-    }
-    
-    /**
-     * Sets the amount of time for which a token is valid from when the original authentication took place.
-     * 
-     * @param lifetime amount of time for which a token is valid
-     */
-    public void setAuthnLifetime(@Nonnull final Duration lifetime) {
-        ifInitializedThrowUnmodifiabledComponentException();
-        
-        Constraint.isNotNull(lifetime, "Token authentication lifetime cannot be null");
-        Constraint.isFalse(lifetime.isNegative(), "Token authentication lifetime cannot be negative");
-        
-        authnLifetimeLookupStrategy = FunctionSupport.constant(lifetime);
-    }
-    
-    /**
-     * Set the lookup strategy used to locate the amount of time for which a token is valid from when the original 
-     * authentication took place.
-     * 
-     * @param strategy the strategy
-     * 
-     * @since 2.2.0
-     */
-    public void setAuthnLifetimeLookupStrategy(@Nonnull final Function<ProfileRequestContext, Duration> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
-        ifDestroyedThrowDestroyedComponentException();
-
-        authnLifetimeLookupStrategy = Constraint.isNotNull(strategy,
-                "AuthnLifetime Lookup Strategy can not be null");
-    }
-
- // Checkstyle: CyclomaticComplexity|MethodLength OFF
-    @Override
-    public void doValidate(@Nonnull final JWTClaimsSet claimsSet, @Nonnull final ProfileRequestContext context) 
-            throws JWTValidationException {
-       
-        if (!requested.test(context)) {
-            //not requested, so nothing to check.
-            return;
-        } else {
-            
-            try { 
-                final Duration authnLifetime = authnLifetimeLookupStrategy.apply(context);
-                final Date authTimeDate = claimsSet.getDateClaim(IDTokenClaims.AUTHENTICATION_TIME.getClaimName());
-                
-                if (authTimeDate == null) {
-                    throw new JWTValidationException("No authentication time found in token");
-                }
-                if (authnLifetime == null) {
-                    throw new JWTValidationException("No authentication lifetime set");
-                }
-                
-                if (authnLifetime.equals(Duration.ofSeconds(0))) {
-                    // Now assume forced authentication semantics, the authentication must have happened after the 
-                    // authentication request was made to the OP
-                    if (authnRequestTimeLookupStrategy == null) {
-                        log.warn("Maximum authentication age of 0 seconds requested, but no "
-                                + "authentication request time lookup strategy set, can not check for a fresh "
-                                + "authentication");
-                        throw new JWTValidationException("Maximum authentication age of 0 seconds requested, but no "
-                                + "authentication request time lookup strategy set, can not check for a fresh "
-                                + "authentication");
-                    }
-                    final Instant authnRequestTime = authnRequestTimeLookupStrategy.apply(context);
-                    
-                    if (authnRequestTime == null) {
-                        log.warn("Maximum authentication age of 0 seconds requested, but no "
-                                + "authentication request time could be found, can not check for a fresh "
-                                + "authentication");
-                        throw new JWTValidationException("Maximum authentication age of 0 seconds requested, but no "
-                                + "authentication request time could be found, can not check for a fresh "
-                                + "authentication");
-                    }
-                    
-                    // Check authTime is after the time which the authentication request was made
-                    if (authTimeDate.toInstant().isBefore(authnRequestTime)) {
-                        log.warn("JWT token authentication time is not valid. Authentication is not fresh but max_age=0"
-                                + " was requested, re-authentication did not occur");
-                        throw new JWTValidationException("JWT token authentication time is not valid. Authentication "
-                                + "is not fresh but max_age=0 was requested, re-authentication did not occur");
-                    }
-                    
-                } else {             
-                    final Instant authTime = authTimeDate.toInstant();
-                    final Instant now = Instant.now();
-                    final Instant latestValid = now.plus(clockSkew);
-                    final Instant expiration = authTime.plus(clockSkew).plus(authnLifetime);
-                    
-                    // Check time of authentication wasn't in the future
-                    if (authTime.isAfter(latestValid)) {
-                        log.warn("Authentication is not yet valid: auth_time was {}, latest valid is: {}",
-                                authTime, latestValid);
-                        throw new JWTValidationException("JWT token authentication time is not yet valid");
-                    }
-    
-                    // Check time of authentication has not expired
-                    if (expiration.isBefore(now)) {
-                        log.warn(
-                                "Authentication has expired: auth_time was '{}', "
-                                + "expired at: '{}', current time: '{}'",
-                                authTime, expiration, now);
-                        throw new JWTValidationException("JWT token authentication time has expired");
-                    }
-                    //is OK.
-                }
-                
-            } catch (final ParseException e) {
-                throw new JWTValidationException("Autentication forced, but no authentication time found in token",e);
-            }
-        }
-        
-    }
-
- // Checkstyle: CyclomaticComplexity|MethodLength ON
-}
diff --git a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jwt/claims/impl/AuthenticationTimeClaimsValidatorTest.java b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jwt/claims/impl/AuthenticationTimeClaimsValidatorTest.java
deleted file mode 100644
index 5dbe72a..0000000
--- a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jwt/claims/impl/AuthenticationTimeClaimsValidatorTest.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/* 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.oidc.security.jwt.claims.impl;
-
-import java.time.Duration;
-import java.time.Instant;
-
-import javax.annotation.Nonnull;
-
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.nimbusds.jwt.JWTClaimsSet;
-
-import net.shibboleth.oidc.jwt.claims.JWTValidationException;
-import net.shibboleth.shared.component.ComponentInitializationException;
-
-/** Test for the {@link AuthenticationTimeClaimsValidator}. */
-public class AuthenticationTimeClaimsValidatorTest extends AbstractClaimsValidatorTest {
-    
-    /** The validator to test.*/
-    @Nonnull private AuthenticationTimeClaimsValidator validator;
-
-    
-    @Override
-    @BeforeMethod
-    public void setup() throws ComponentInitializationException {
-        super.setup();
-        validator = new AuthenticationTimeClaimsValidator();
-    }
-    
-    @Test
-    public void doValidateTest() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), Instant.now().getEpochSecond()).build();
-        validator.setId("test-validator");   
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        validator.setClockSkew(Duration.ofSeconds(0));
-        validator.initialize();
-        validator.validate(claimsSet, prc);   
-    }
-    
-    @Test
-    public void doValidateTest_UseAuthnStrategy() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), Instant.now().getEpochSecond()).build();
-        validator.setId("test-validator");   
-        validator.setAuthnLifetimeLookupStrategy(prc -> Duration.ofMinutes(1));
-        validator.setClockSkew(Duration.ofSeconds(0));
-        validator.initialize();
-        validator.validate(claimsSet, prc);   
-    }
-    
-    @Test
-    public void doValidateTest_DefaultAuthnTime() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), Instant.now().getEpochSecond()).build();
-        validator.setId("test-validator");   
-        validator.setClockSkew(Duration.ofSeconds(0));
-        validator.initialize();
-        validator.validate(claimsSet, prc);   
-    }
-    
-    @Test
-    public void doValidateTestWithinLifetime() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), 
-                Instant.now().minus(Duration.ofSeconds(30)).getEpochSecond()).build();
-        validator.setId("test-validator");   
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        validator.setClockSkew(Duration.ofSeconds(0));
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-    @Test
-    public void doValidateNoClaimButNotActive() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().build();
-        validator.setActivationCondition((prc,claims) -> false);
-        validator.setId("test-validator");   
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-    @Test(expectedExceptions = JWTValidationException.class)
-    public void doRejectedTestCanNotParseDate() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(),"not-a-date").build();
-        validator.setId("test-validator");   
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-    @Test(expectedExceptions = JWTValidationException.class)
-    public void doRejectedTest() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), 
-                Instant.now().minus(Duration.ofMinutes(10)).getEpochSecond()).build();
-        validator.setId("test-validator");   
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        validator.setClockSkew(Duration.ofMinutes(0));
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-    @Test(expectedExceptions = JWTValidationException.class)
-    public void doRejectedInTheFuture() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), 
-                Instant.now().plus(Duration.ofSeconds(30)).getEpochSecond()).build();
-        validator.setId("test-validator");   
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        //set clockskew to 10 seconds, and JWT is 30 seconds in the future, so should throw
-        validator.setClockSkew(Duration.ofSeconds(10));
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-    @Test
-    public void doRejectedInTheFutureButInsideSkew() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), 
-                Instant.now().plus(Duration.ofSeconds(30)).getEpochSecond()).build();
-        validator.setId("test-validator");   
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        //set clockskew to 60 seconds, and JWT is 30 seconds in the future, so should be fine
-        validator.setClockSkew(Duration.ofSeconds(60));
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-    @Test(expectedExceptions = JWTValidationException.class)
-    public void doRejectedNoClaim() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().build();
-        validator.setId("test-validator");   
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-    @Test(expectedExceptions = JWTValidationException.class)
-    public void doRejectedForceAuthenticationRequestButOldAuthnTime() 
-            throws JWTValidationException, ComponentInitializationException {
-        // Authentication occurs 10 second before the authn request was sent
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), 
-                Instant.now().minus(Duration.ofSeconds(10)).getEpochSecond()).build();
-        validator.setId("test-validator");   
-        // returning 0 seconds 'signals' forced authentication
-        validator.setAuthnLifetime(Duration.ofSeconds(0));
-        validator.setAuthnRequestTimeLookupStrategy(prc -> Instant.now());
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-
-    
-    @Test
-    public void doValidForceAuthenticationRequest() 
-            throws JWTValidationException, ComponentInitializationException {
-        // Authentication occurs 10 second after the authn request was sent
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().claim(
-                IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), 
-                Instant.now().plus(Duration.ofSeconds(10)).getEpochSecond()).build();
-        validator.setId("test-validator");   
-        // returning 0 seconds 'signals' forced authentication
-        validator.setAuthnLifetime(Duration.ofSeconds(0));
-        validator.setAuthnRequestTimeLookupStrategy(prc -> Instant.now());
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-    /**
-     * Would fail, but the claim was not requested, so it is not checked.
-     * 
-     * @throws JWTValidationException on error.
-     * @throws ComponentInitializationException on error.
-     */
-    @Test
-    public void doValidateAuthTimeNotRequested() throws JWTValidationException, ComponentInitializationException {
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().build();
-        validator.setId("test-validator");   
-        validator.setRequested(prc -> false);
-        validator.setAuthnLifetime(Duration.ofMinutes(1));
-        validator.initialize();
-        validator.validate(claimsSet, prc);
-    }
-    
-}
diff --git a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jwt/claims/impl/ChainingJWTClaimsValidatorTest.java b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jwt/claims/impl/ChainingJWTClaimsValidatorTest.java
index 7e1f340..16b1690 100644
--- a/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jwt/claims/impl/ChainingJWTClaimsValidatorTest.java
+++ b/oidc-common-crypto-impl/src/test/java/net/shibboleth/oidc/security/jwt/claims/impl/ChainingJWTClaimsValidatorTest.java
@@ -86,14 +86,6 @@ public class ChainingJWTClaimsValidatorTest extends AbstractClaimsValidatorTest{
         usernameExactV.initialize();
         validators.add(usernameExactV);
         
-        //auth time
-        final AuthenticationTimeClaimsValidator authTimeV = new AuthenticationTimeClaimsValidator();
-        authTimeV.setId("auth-time-validator");
-        authTimeV.setAuthnLifetime(Duration.ofMinutes(1));
-        authTimeV.setRequested(prc -> true);
-        authTimeV.initialize();
-        validators.add(authTimeV);
-        
         //nonce
         final ExactMatchClaimsValidator nonceV = new ExactMatchClaimsValidator();
         nonceV.setId("nonce-validator");
@@ -318,23 +310,4 @@ public class ChainingJWTClaimsValidatorTest extends AbstractClaimsValidatorTest{
         validation.validate(claimsSet, prc);        
     }
     
-    @Test(expectedExceptions = JWTValidationException.class)
-    public void validationFailedAuthTimeTooFarInPast() throws ComponentInitializationException, JWTValidationException {
-        
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
-                .issuer("issuer")
-                .subject("jdoe")
-                .expirationTime(Date.from(Instant.now().plus(Duration.ofMinutes(10))))
-                .audience("audience")
-                .notBeforeTime(Date.from(Instant.now().minus(Duration.ofMinutes(1))))
-                .issueTime(Date.from(Instant.now()))
-                .claim(IDTokenClaims.AUTHENTICATION_TIME.getClaimName(), 
-                        Instant.now().minus(Duration.ofSeconds(300)).getEpochSecond())
-                .claim("username", "jdoe")
-                .claim(IDTokenClaims.NONCE.getClaimName(), "nonce")
-                .build();        
-
-        validation.validate(claimsSet, prc);        
-    }
-
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list