[java-idp-oidc] branch main updated: JOIDC-88 Honoring semantics for forceAuthn flag in the same manner as SAML
Henri Mikkonen
henri.mikkonen at iki.fi
Mon Apr 11 15:23:19 UTC 2022
This is an automated email from the git hooks/post-receive script.
hjmikkon 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=4f799a8dc2726d0df6137502147b314e51cddffc
The following commit(s) were added to refs/heads/main by this push:
new 4f799a8d JOIDC-88 Honoring semantics for forceAuthn flag in the same manner as SAML
4f799a8d is described below
commit 4f799a8dc2726d0df6137502147b314e51cddffc
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Mon Apr 11 18:22:29 2022 +0300
JOIDC-88 Honoring semantics for forceAuthn flag in the same manner as SAML
https://shibboleth.atlassian.net/browse/JOIDC-88
Added configurable forceAuthnPredicate for the InitializeAuthenticationContext action.
It’s set to ForceAuthnProfileConfigPredicate (protocol-independent) by default.
---
.../impl/InitializeAuthenticationContext.java | 24 ++++++++++++++++
.../impl/InitializeAuthenticationContextTest.java | 32 ++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeAuthenticationContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeAuthenticationContext.java
index 8c406b06..39fb9cb1 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeAuthenticationContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeAuthenticationContext.java
@@ -19,9 +19,11 @@ package net.shibboleth.idp.plugin.oidc.op.profile.impl;
import java.time.Duration;
import java.util.function.Function;
+import java.util.function.Predicate;
import javax.annotation.Nonnull;
+import net.shibboleth.idp.authn.config.navigate.ForceAuthnProfileConfigPredicate;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestLoginHintLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestMaxAgeLookupFunction;
@@ -59,6 +61,9 @@ public class InitializeAuthenticationContext extends AbstractOIDCAuthenticationR
/** Strategy used to obtain the request max_age value. */
@Nonnull private Function<ProfileRequestContext, Duration> maxAgeLookupStrategy;
+ /** Extracts forceAuthn property from profile config. */
+ @Nonnull private Predicate<ProfileRequestContext> forceAuthnPredicate;
+
/**
* Constructor.
*/
@@ -66,6 +71,7 @@ public class InitializeAuthenticationContext extends AbstractOIDCAuthenticationR
promptLookupStrategy = new DefaultRequestedPromptLookupFunction();
loginHintLookupStrategy = new DefaultRequestLoginHintLookupFunction();
maxAgeLookupStrategy = new DefaultRequestMaxAgeLookupFunction();
+ forceAuthnPredicate = new ForceAuthnProfileConfigPredicate();
}
/**
@@ -99,6 +105,19 @@ public class InitializeAuthenticationContext extends AbstractOIDCAuthenticationR
maxAgeLookupStrategy = Constraint.isNotNull(strategy, "MaxAgeLookupStrategy lookup strategy cannot be null");
}
+ /**
+ * Set the predicate to apply to derive the message-independent forced authn default.
+ *
+ * @param condition condition to set
+ *
+ * @since 3.1.0
+ */
+ public void setForceAuthnPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ forceAuthnPredicate = Constraint.isNotNull(condition, "Forced authentication predicate cannot be null");
+ }
+
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -118,6 +137,11 @@ public class InitializeAuthenticationContext extends AbstractOIDCAuthenticationR
authnCtx.setIsPassive(prompt.contains(Prompt.Type.NONE));
authnCtx.setForceAuthn(prompt.contains(Prompt.Type.LOGIN));
}
+
+ if (!authnCtx.isForceAuthn()) {
+ authnCtx.setForceAuthn(forceAuthnPredicate.test(profileRequestContext));
+ }
+
final String loginHint = loginHintLookupStrategy.apply(profileRequestContext);
if (loginHint != null) {
authnCtx.setHintedName(loginHint);
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeAuthenticationContextTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeAuthenticationContextTest.java
index 7c9b62b6..4cb3ed75 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeAuthenticationContextTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/InitializeAuthenticationContextTest.java
@@ -38,6 +38,7 @@ import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.base.Predicates;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.ResponseType;
import com.nimbusds.oauth2.sdk.Scope;
@@ -103,6 +104,37 @@ public class InitializeAuthenticationContextTest {
Assert.assertEquals(authnCtx.getMaxAge(), Duration.ofSeconds(5));
}
+ @Test
+ public void testOIDCAuthnRequestWithoutPrompt() {
+ final AuthenticationRequest req = new AuthenticationRequest.Builder(new ResponseType("code"), new Scope("openid"),
+ new ClientID("000123"), URI.create("https://example.com/callback")).state(new State()).build();
+ prc.getInboundMessageContext().setMessage(req);
+ final Event event = action.execute(requestCtx);
+ ActionTestingSupport.assertProceedEvent(event);
+ final AuthenticationContext authnCtx = prc.getSubcontext(AuthenticationContext.class, false);
+ Assert.assertNotNull(authnCtx);
+ Assert.assertFalse(authnCtx.isForceAuthn());
+ Assert.assertFalse(authnCtx.isPassive());
+ Assert.assertNull(authnCtx.getMaxAge());
+ }
+
+ @Test
+ public void testOIDCAuthnRequestWithoutPromptForceAuthnViaPredicate() throws ComponentInitializationException {
+ action = new InitializeAuthenticationContext();
+ action.setForceAuthnPredicate(Predicates.alwaysTrue());
+ action.initialize();
+ final AuthenticationRequest req = new AuthenticationRequest.Builder(new ResponseType("code"), new Scope("openid"),
+ new ClientID("000123"), URI.create("https://example.com/callback")).state(new State()).build();
+ prc.getInboundMessageContext().setMessage(req);
+ final Event event = action.execute(requestCtx);
+ ActionTestingSupport.assertProceedEvent(event);
+ final AuthenticationContext authnCtx = prc.getSubcontext(AuthenticationContext.class, false);
+ Assert.assertNotNull(authnCtx);
+ Assert.assertTrue(authnCtx.isForceAuthn());
+ Assert.assertFalse(authnCtx.isPassive());
+ Assert.assertNull(authnCtx.getMaxAge());
+ }
+
@Test(expectedExceptions = ConstraintViolationException.class)
public void testSetNullLoginHintLookupStrategy() throws Exception {
action = new InitializeAuthenticationContext();
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list