[java-idp-oidc] branch main updated: JOIDC-246 - Support disallowedFeatures to block essential acr requests

Scott Cantor cantor.2 at osu.edu
Tue Jun 10 15:01:46 UTC 2025


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

scantor pushed a commit to branch main
in repository java-idp-oidc.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=77db8da974a1e75e087e5ca6cf05f8bb403272f5

The following commit(s) were added to refs/heads/main by this push:
     new 77db8da9 JOIDC-246 - Support disallowedFeatures to block essential acr requests
77db8da9 is described below

commit 77db8da974a1e75e087e5ca6cf05f8bb403272f5
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jun 10 11:01:42 2025 -0400

    JOIDC-246 - Support disallowedFeatures to block essential acr requests
    
    https://shibboleth.atlassian.net/browse/JOIDC-246
---
 .../profile/impl/ProcessRequestedAuthnContext.java | 55 ++++++++++++++++++----
 1 file changed, 46 insertions(+), 9 deletions(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ProcessRequestedAuthnContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ProcessRequestedAuthnContext.java
index 13b2753d..d57831de 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ProcessRequestedAuthnContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ProcessRequestedAuthnContext.java
@@ -15,7 +15,6 @@
 package net.shibboleth.idp.plugin.oidc.op.profile.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import net.shibboleth.idp.authn.AuthnEventIds;
 import net.shibboleth.idp.authn.context.AuthenticationContext;
@@ -23,13 +22,19 @@ import net.shibboleth.idp.authn.context.PreferredPrincipalContext;
 import net.shibboleth.idp.authn.context.RequestedPrincipalContext;
 import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
 import net.shibboleth.oidc.authn.principal.AuthenticationContextClassReferencePrincipal;
+import net.shibboleth.oidc.profile.config.OIDCAuthenticationProfileConfiguration;
 import net.shibboleth.oidc.profile.config.navigate.AcrClaimAlwaysEssentialLookupFunction;
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
 import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration;
 import org.slf4j.Logger;
@@ -69,12 +74,15 @@ public class ProcessRequestedAuthnContext extends AbstractOIDCAuthenticationResp
 
     /** Strategy used to obtain the requested acr values. */
     @NonnullAfterInit private Function<ProfileRequestContext, List<ACR>> acrLookupStrategy;
+
+    /** Strategy used to look up a {@link RelyingPartyContext} for configuration options. */
+    @Nonnull private Function<ProfileRequestContext,RelyingPartyContext> relyingPartyContextLookupStrategy;
     
     /** Strategy used to obtain whether all arc claims requests should be treated as Essential. */
     @Nonnull private Predicate<ProfileRequestContext> acrAlwaysEssentialLookupStrategy;
 
     /** Authentication context. */
-    @Nullable private AuthenticationContext authenticationContext;
+    @NonnullBeforeExec private AuthenticationContext authenticationContext;
 
     /** acr values. */
     private List<ACR> acrValues;
@@ -86,9 +94,25 @@ public class ProcessRequestedAuthnContext extends AbstractOIDCAuthenticationResp
      * Constructor.
      */
     public ProcessRequestedAuthnContext() {
+        relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
         acrAlwaysEssentialLookupStrategy = new AcrClaimAlwaysEssentialLookupFunction();
     }
 
+
+    /**
+     * Set the strategy used to return the {@link RelyingPartyContext} for configuration options.
+     * 
+     * @param strategy lookup strategy
+     * 
+     * @since 4.3.0
+     */
+    public void setRelyingPartyContextLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,RelyingPartyContext> strategy) {
+        checkSetterPreconditions();
+        relyingPartyContextLookupStrategy =
+                Constraint.isNotNull(strategy, "RelyingPartyContext lookup strategy cannot be null");
+    }
+    
     /**
      * Set the strategy used to locate the requested acr values.
      * 
@@ -120,7 +144,6 @@ public class ProcessRequestedAuthnContext extends AbstractOIDCAuthenticationResp
         }
     }
 
-    // Checkstyle: CyclomaticComplexity OFF
     /** {@inheritDoc} */
     @Override
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -159,9 +182,8 @@ public class ProcessRequestedAuthnContext extends AbstractOIDCAuthenticationResp
         
         return true;
     }
-    // Checkstyle: CyclomaticComplexity ON
 
-    // Checkstyle: CyclomaticComplexity OFF
+// Checkstyle: CyclomaticComplexity OFF
     /** {@inheritDoc} */
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -193,26 +215,41 @@ public class ProcessRequestedAuthnContext extends AbstractOIDCAuthenticationResp
                 principals.add(new AuthenticationContextClassReferencePrincipal(acr));
             }
         }
+        
         if (principals.isEmpty()) {
             log.debug("{} request did not contain any acr values, nothing to do", getLogPrefix());
             return;
         }
+        
         if (isEssential || acrAlwaysEssentialLookupStrategy.test(profileRequestContext)) {
+            
+            // Check if permitted.
+            final RelyingPartyContext rpContext = relyingPartyContextLookupStrategy.apply(profileRequestContext);
+            final ProfileConfiguration profileConfig = rpContext==null ? null : rpContext.getProfileConfig();
+            if (profileConfig != null) {            
+                if (profileConfig.isFeatureDisallowed(
+                        profileRequestContext, OIDCAuthenticationProfileConfiguration.FEATURE_ESSENTIAL_ACR_REQUEST)) {
+                    log.warn("{} Incoming essential acr request disallowed by profile configuration", getLogPrefix());
+                    ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
+                    return;
+                }
+            }
+            
             final RequestedPrincipalContext rpCtx = new RequestedPrincipalContext();
             rpCtx.setOperator(AuthnContextComparisonTypeEnumeration.EXACT.toString());
             rpCtx.setRequestedPrincipals(principals);
             // TODO: When 5.2 API supported, call setImposedLocally to false.
-            assert authenticationContext != null;
             authenticationContext.addSubcontext(rpCtx, true);
             log.debug("{} Created requested principal context", getLogPrefix());
             return;
         }
+        
         final PreferredPrincipalContext ppCtx = new PreferredPrincipalContext();
         ppCtx.setPreferredPrincipals(principals);
-        assert authenticationContext != null;
         authenticationContext.addSubcontext(ppCtx, true);
+        
         log.debug("{} Created preferred principal context", getLogPrefix());
     }
-    // Checkstyle: CyclomaticComplexity ON
-
+// Checkstyle: CyclomaticComplexity ON
+    
 }
\ No newline at end of file

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


More information about the commits mailing list