[java-identity-provider] branch main updated: IDP-2309 - External Authn API should support direct event signaling
Scott Cantor
cantor.2 at osu.edu
Wed Mar 5 21:03:04 UTC 2025
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=221e8b1af84ca1840e3270e7420d17f7be18f756
The following commit(s) were added to refs/heads/main by this push:
new 221e8b1af IDP-2309 - External Authn API should support direct event signaling
221e8b1af is described below
commit 221e8b1af84ca1840e3270e7420d17f7be18f756
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Mar 5 16:03:01 2025 -0500
IDP-2309 - External Authn API should support direct event signaling
https://shibboleth.atlassian.net/browse/IDP-2309
---
.../idp/authn/ExternalAuthentication.java | 7 ++++
.../context/ExternalAuthenticationContext.java | 31 +++++++++++++++-
.../idp/authn/impl/ExternalAuthenticationImpl.java | 7 +++-
.../authn/impl/ValidateExternalAuthentication.java | 15 +++++++-
.../impl/ValidateExternalAuthenticationTest.java | 42 +++++++++++++++++++++-
5 files changed, 98 insertions(+), 4 deletions(-)
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
index fe356a011..91bdb03c6 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/ExternalAuthentication.java
@@ -78,6 +78,13 @@ public abstract class ExternalAuthentication {
/** Request attribute to which an exception may be bound. */
@Nonnull @NotEmpty public static final String AUTHENTICATION_EXCEPTION_KEY = "authnException";
+ /**
+ * Request attribute to which a webflow event may be bound.
+ *
+ * @since 5.2.0
+ */
+ @Nonnull @NotEmpty public static final String AUTHENTICATION_EVENT_KEY = "authnEvent";
+
/** Request attribute to which a signal not to cache the result may be bound. */
@Nonnull @NotEmpty public static final String DONOTCACHE_KEY = "doNotCache";
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/ExternalAuthenticationContext.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/ExternalAuthenticationContext.java
index ee8c122a3..781570349 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/ExternalAuthenticationContext.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/ExternalAuthenticationContext.java
@@ -64,7 +64,10 @@ public final class ExternalAuthenticationContext extends BaseContext {
/** Exception. */
@Nullable private Exception authnException;
-
+
+ /** Event. */
+ @Nullable private String authnEvent;
+
/** Flag preventing caching of result for SSO. */
private boolean doNotCache;
@@ -258,6 +261,32 @@ public final class ExternalAuthenticationContext extends BaseContext {
return this;
}
+ /**
+ * Get a Spring Web Flow event from the authentication process.
+ *
+ * @return an event string
+ *
+ * @since 5.2.0
+ */
+ @Nullable public String getAuthnEvent() {
+ return authnEvent;
+ }
+
+ /**
+ * Set a Spring Web Flow event from the authentication process.
+ *
+ * @param event event to set
+ *
+ * @return this context
+ *
+ * @since 5.2.0
+ */
+ @Nonnull public ExternalAuthenticationContext setAuthnEvent(@Nullable final String event) {
+ authnEvent = event;
+
+ return this;
+ }
+
/**
* Get the "do not cache" flag.
*
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
index e6b73841e..d2e02e1b1 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ExternalAuthenticationImpl.java
@@ -158,7 +158,12 @@ public class ExternalAuthenticationImpl extends ExternalAuthentication {
if (attr != null && attr instanceof Exception) {
extContext.setAuthnException((Exception) attr);
}
-
+
+ attr = request.getAttribute(AUTHENTICATION_EVENT_KEY);
+ if (attr != null && attr instanceof String) {
+ extContext.setAuthnEvent((String) attr);
+ }
+
attr = request.getAttribute(DONOTCACHE_KEY);
if (attr != null && attr instanceof Boolean) {
extContext.setDoNotCache((Boolean) attr);
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
index 8d85f529d..6e0cf2d6e 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
@@ -167,9 +167,21 @@ public class ValidateExternalAuthentication extends AbstractAuditingValidationAc
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
@Nonnull final AuthenticationContext authenticationContext) {
+ final String authnEvent = extContext.getAuthnEvent();
final Exception authnExp = extContext.getAuthnException();
final String principalName = extContext.getPrincipalName();
- if (authnExp != null) {
+
+ if (authnEvent != null) {
+ log.info("{} External authentication produced event: {}", getLogPrefix(), authnEvent,
+ extContext.getAuthnException());
+ if (authnExp != null) {
+ handleError(profileRequestContext, authenticationContext, authnExp, authnEvent);
+ } else {
+ handleError(profileRequestContext, authenticationContext, extContext.getAuthnError(), authnEvent);
+ }
+ recordFailure(profileRequestContext);
+ return;
+ } else if (authnExp != null) {
log.info("{} External authentication produced exception", getLogPrefix(), extContext.getAuthnException());
handleError(profileRequestContext, authenticationContext, authnExp,
AuthnEventIds.AUTHN_EXCEPTION);
@@ -183,6 +195,7 @@ public class ValidateExternalAuthentication extends AbstractAuditingValidationAc
recordFailure(profileRequestContext);
return;
}
+
if (extContext.getSubject() != null) {
log.info("{} External authentication succeeded for Subject", getLogPrefix());
} else if (extContext.getPrincipal() != null) {
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthenticationTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthenticationTest.java
index 0d7ce5912..2894c362c 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthenticationTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthenticationTest.java
@@ -38,6 +38,7 @@ import net.shibboleth.idp.authn.principal.ProxyAuthenticationPrincipal;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
import net.shibboleth.idp.authn.testing.TestPrincipal;
import net.shibboleth.idp.profile.testing.ActionTestingSupport;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.testing.ConstantSupplier;
@@ -60,6 +61,7 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
action = new ValidateExternalAuthentication();
final MockHttpServletRequest request = new MockHttpServletRequest();
action.setHttpServletRequestSupplier(new ConstantSupplier<>(request));
+ action.setClassifiedMessages(CollectionSupport.singletonMap("Zorkmid2", CollectionSupport.listOf("foo", "bar")));
action.initialize();
}
@@ -200,4 +202,42 @@ public class ValidateExternalAuthenticationTest extends BaseAuthenticationContex
Assert.assertNull(ac.getAuthenticationResult());
}
-}
+ @Test public void testEvent() {
+ final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
+ assert ac != null;
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
+ eac.setAuthnEvent("Zorkmid");
+
+ final Event event = action.execute(src);
+ ActionTestingSupport.assertEvent(event, "Zorkmid");
+ Assert.assertNull(ac.getAuthenticationResult());
+ }
+
+ @Test public void testEventAndMappedError() {
+ final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
+ assert ac != null;
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
+ eac.setAuthnEvent("Zorkmid");
+ eac.setAuthnError("foo");
+
+ final Event event = action.execute(src);
+ ActionTestingSupport.assertEvent(event, "Zorkmid2");
+ Assert.assertNull(ac.getAuthenticationResult());
+ }
+
+ @Test public void testEventAndUnmappedError() {
+ final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
+ assert ac != null;
+ final ExternalAuthenticationContext eac =
+ (ExternalAuthenticationContext) ac.addSubcontext(new ExternalAuthenticationContext(ext), true);
+ eac.setAuthnEvent("Zorkmid");
+ eac.setAuthnError("Foo");
+
+ final Event event = action.execute(src);
+ ActionTestingSupport.assertEvent(event, "Zorkmid");
+ Assert.assertNull(ac.getAuthenticationResult());
+ }
+
+}
\ 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