[java-idp-plugin-duo] branch main updated: Add cleanup hook to the JWT Claims verifier

Phil Smart philip.smart at jisc.ac.uk
Wed Dec 23 14:50:26 UTC 2020


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

philsmart pushed a commit to branch main
in repository java-idp-plugin-duo.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-duo.git;a=commit;h=64445be88fec590baae3ca0ed8688e5ddf4f3755

The following commit(s) were added to refs/heads/main by this push:
       new  64445be   Add cleanup hook to the JWT Claims verifier
64445be is described below

commit 64445be88fec590baae3ca0ed8688e5ddf4f3755
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Dec 23 14:50:20 2020 +0000

    Add cleanup hook to the JWT Claims verifier
    
    Executes on either successful or unsuccessful verification e.g. to
    cleanup the nonce
---
 .../authn/duo/DefaultDuoOIDCIntegration.java       |  2 +
 .../idp/plugin/authn/duo/DuoOIDCIntegration.java   |  2 +
 .../plugin/authn/duo/impl/ValidateTokenClaims.java | 53 +++++++++++++++++++++-
 .../flows/authn/DuoOIDC/duo-oidc-authn-beans.xml   |  4 ++
 4 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DefaultDuoOIDCIntegration.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DefaultDuoOIDCIntegration.java
index 7884188..07c8c36 100644
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DefaultDuoOIDCIntegration.java
+++ b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DefaultDuoOIDCIntegration.java
@@ -29,6 +29,7 @@ import javax.security.auth.Subject;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.annotation.constraint.ThreadSafeAfterInit;
 import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
 import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@@ -40,6 +41,7 @@ import net.shibboleth.utilities.java.support.primitive.StringSupport;
  * Wrapper for use with Duo OIDC integrations. Class is an initializable component and is hence
  * made effectively immutable once initialized.
  */
+ at ThreadSafeAfterInit
 public class DefaultDuoOIDCIntegration extends AbstractInitializableComponent implements DuoOIDCIntegration{
     
     /** API host. */
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCIntegration.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCIntegration.java
index 11cdf67..da8800c 100644
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCIntegration.java
+++ b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCIntegration.java
@@ -18,6 +18,7 @@
 package net.shibboleth.idp.plugin.authn.duo;
 
 import javax.annotation.Nonnull;
+import javax.annotation.concurrent.Immutable;
 
 import net.shibboleth.idp.authn.principal.PrincipalSupportingComponent;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
@@ -26,6 +27,7 @@ import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
  * Interface to a particular Duo OIDC integration point. In part replaces
  * OIDC metadata as that is not supported by Duo.
  */
+ at Immutable
 public interface DuoOIDCIntegration extends PrincipalSupportingComponent {
     
     /**
diff --git a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateTokenClaims.java b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateTokenClaims.java
index 057b1dc..a01dfa8 100644
--- a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateTokenClaims.java
+++ b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateTokenClaims.java
@@ -18,6 +18,7 @@
 package net.shibboleth.idp.plugin.authn.duo.impl;
 
 import java.text.ParseException;
+import java.util.function.Consumer;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -83,6 +84,9 @@ public class ValidateTokenClaims extends AbstractDuoAuthenticationAction {
     /** The parsed claimset. */
     @Nullable private JWTClaimsSet claimsSet;
     
+    /** A cleanup hook to execute after either a successful or unsuccessful claims validation. */
+    @Nullable private Consumer<ProfileRequestContext> cleanupHook;
+    
     /** The JWT claims verify used to verify the claimsset.*/
     @NonnullAfterInit private JWTClaimsSetVerifier<ProfileRequestJWTSecurityContext> claimsVerifier;
     
@@ -95,6 +99,27 @@ public class ValidateTokenClaims extends AbstractDuoAuthenticationAction {
         }
     }
     
+    /**
+     * Get the cleanup hook to execute after either a successful or unsuccessful validation.
+     * 
+     * @return cleanup hook
+     */
+    @Nullable public Consumer<ProfileRequestContext> getCleanupHook() {
+        return cleanupHook;
+    }
+    
+    /**
+     * Set the cleanup hook to execute after either a successful or unsuccessful claims validation.
+     * 
+     * @param hook cleanup hook
+     * 
+     */
+    public void setCleanupHook(@Nullable final Consumer<ProfileRequestContext> hook) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        cleanupHook = hook;
+    }
+    
     /**
      * Set the JWT claims verifier to use.
      * 
@@ -141,14 +166,38 @@ public class ValidateTokenClaims extends AbstractDuoAuthenticationAction {
          
         try {
             claimsVerifier.verify(claimsSet, new ProfileRequestJWTSecurityContext(profileRequestContext));
-            //blank the nonce even if not used
-            duoContext.setNonce(null);
+            if (cleanupHook != null) {
+                cleanupHook.accept(profileRequestContext);
+            }
         } catch (final BadJWTException e) {
             log.error("{} Token verification failed for subject '{}'", getLogPrefix(),claimsSet.getSubject(),e);
             ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
+            if (cleanupHook != null) {
+                cleanupHook.accept(profileRequestContext);
+            }
             return;
         }
         //fine.
         log.debug("{} Token claims are valid for subject '{}'",getLogPrefix(),claimsSet.getSubject());
     }
+    
+    /**
+     * A cleanup hook that removes the 'nonce' parameter from the {@link DuoOIDCAuthenticationContext} so
+     * it could not be reused.
+     */
+    public static class DuoOIDAuthenticationContextCleanupHook implements Consumer<ProfileRequestContext> {
+
+        /** {@inheritDoc} */
+        public void accept(@Nullable final ProfileRequestContext input) {
+            if (input != null) {
+                final AuthenticationContext authnCtx = input.getSubcontext(AuthenticationContext.class);
+                if (authnCtx != null) {
+                    final DuoOIDCAuthenticationContext duoCtx = authnCtx.getSubcontext(DuoOIDCAuthenticationContext.class);
+                    if (duoCtx != null) {
+                        duoCtx.setNonce(null);
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/idp-duo-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/DuoOIDC/duo-oidc-authn-beans.xml b/idp-duo-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/DuoOIDC/duo-oidc-authn-beans.xml
index 7cbcaf8..480d5ce 100644
--- a/idp-duo-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/DuoOIDC/duo-oidc-authn-beans.xml
+++ b/idp-duo-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/DuoOIDC/duo-oidc-authn-beans.xml
@@ -68,8 +68,12 @@
     <bean id="ValidateTokenSignature" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.duo.impl.ValidateTokenSignature" />
         
+    <bean id="shibboleth.authn.DuoOIDC.jwt.claims.DefaultCleanupHook" 
+        class="net.shibboleth.idp.plugin.authn.duo.impl.ValidateTokenClaims.DuoOIDAuthenticationContextCleanupHook" />
+        
     <bean id="ValidateTokenClaims" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.duo.impl.ValidateTokenClaims" 
+        p:cleanupHook="#{getObject('shibboleth.authn.DuoOIDC.jwt.claims.CleanUpHook') ?: getObject('shibboleth.authn.DuoOIDC.jwt.claims.DefaultCleanupHook')}"
         p:claimsVerifier="#{getObject('shibboleth.authn.DuoOIDC.DuoTokenClaimsVerifier') ?: getObject('shibboleth.authn.DuoOIDC.DefaultDuoTokenClaimsVerifier')}"/>
 
     <bean id="shibboleth.authn.DuoOIDC.DefaultDuoTokenClaimsVerifier"

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


More information about the commits mailing list