[java-identity-provider] branch master updated: IDP-1494 - Login flow for proxied SAML authentication
Scott Cantor
cantor.2 at osu.edu
Tue Dec 3 09:13:15 EST 2019
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=98d8662e0d78c06f1fbd23cc06bc44b4e268d45c
The following commit(s) were added to refs/heads/master by this push:
new 98d8662 IDP-1494 - Login flow for proxied SAML authentication
98d8662 is described below
commit 98d8662e0d78c06f1fbd23cc06bc44b4e268d45c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Dec 3 09:13:08 2019 -0500
IDP-1494 - Login flow for proxied SAML authentication
https://issues.shibboleth.net/jira/browse/IDP-1494
Revert error handling around discovery.
Move all conditional discovery logic into parent flow.
Install discovery hook into obvious login flows.
---
.../idp/authn/proxy/impl/ExtractDiscoveryResponse.java | 10 +++++++---
.../idp/authn/proxy/impl/ExtractDiscoveryResponseTest.java | 6 ++++--
.../resources/system/flows/authn/authn-abstract-flow.xml | 4 ++--
.../resources/system/flows/authn/external-authn-flow.xml | 12 +++++++++++-
.../resources/system/flows/authn/function-authn-flow.xml | 12 +++++++++++-
.../src/main/resources/system/flows/authn/mfa-authn-flow.xml | 12 +++++++++++-
.../resources/system/flows/authn/remoteuser-authn-flow.xml | 12 +++++++++++-
.../main/resources/system/flows/authn/saml-authn-flow.xml | 12 ++++++------
8 files changed, 63 insertions(+), 17 deletions(-)
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/proxy/impl/ExtractDiscoveryResponse.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/proxy/impl/ExtractDiscoveryResponse.java
index 6b57360..2dad4ed 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/proxy/impl/ExtractDiscoveryResponse.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/proxy/impl/ExtractDiscoveryResponse.java
@@ -21,9 +21,11 @@ import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import net.shibboleth.idp.authn.AbstractAuthenticationAction;
+import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,9 +34,10 @@ import org.slf4j.LoggerFactory;
* An action that extracts a discovery service result and copies it to the {@link AuthenticationContext}.
*
* @event {@link org.opensaml.profile.action.EventIds#PROCEED_EVENT_ID}
+ * @event {@link AuthnEventIds#NO_CREDENTIALS}
* @pre <pre>ProfileRequestContext.getSubcontext(AuthenticationContext.class) != null</pre>
* @post If getHttpServletRequest() != null, the content of the "entityID" parameter will be
- * added via {@link AuthenticationContext#setAuthenticatingAuthority(String)}.
+ * set via {@link AuthenticationContext#setAuthenticatingAuthority(String)}.
*/
public class ExtractDiscoveryResponse extends AbstractAuthenticationAction {
@@ -49,14 +52,15 @@ public class ExtractDiscoveryResponse extends AbstractAuthenticationAction {
final HttpServletRequest request = getHttpServletRequest();
if (request == null) {
log.error("{} Profile action does not contain an HttpServletRequest", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
return;
}
final String entityID = StringSupport.trimOrNull(request.getParameter("entityID"));
if (entityID == null) {
- log.debug("{} No entityID parameter found", getLogPrefix());
- return;
+ log.info("{} No entityID parameter returned from DS, IdP discovery failed", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
}
authenticationContext.setAuthenticatingAuthority(entityID);
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/proxy/impl/ExtractDiscoveryResponseTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/proxy/impl/ExtractDiscoveryResponseTest.java
index 3e05b67..f003ad4 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/proxy/impl/ExtractDiscoveryResponseTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/proxy/impl/ExtractDiscoveryResponseTest.java
@@ -17,6 +17,8 @@
package net.shibboleth.idp.authn.proxy.impl;
+
+import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.authn.impl.BaseAuthenticationContextTest;
import net.shibboleth.idp.profile.ActionTestingSupport;
@@ -45,14 +47,14 @@ public class ExtractDiscoveryResponseTest extends BaseAuthenticationContextTest
action.initialize();
final Event event = action.execute(src);
- ActionTestingSupport.assertProceedEvent(event);
+ ActionTestingSupport.assertEvent(event, AuthnEventIds.NO_CREDENTIALS);
Assert.assertNull(prc.getSubcontext(AuthenticationContext.class).getAuthenticatingAuthority());
}
@Test public void testFailure() throws Exception {
final Event event = action.execute(src);
- ActionTestingSupport.assertProceedEvent(event);
+ ActionTestingSupport.assertEvent(event, AuthnEventIds.NO_CREDENTIALS);
Assert.assertNull(prc.getSubcontext(AuthenticationContext.class).getAuthenticatingAuthority());
}
diff --git a/idp-conf/src/main/resources/system/flows/authn/authn-abstract-flow.xml b/idp-conf/src/main/resources/system/flows/authn/authn-abstract-flow.xml
index 5491c5b..c9bce65 100644
--- a/idp-conf/src/main/resources/system/flows/authn/authn-abstract-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/authn-abstract-flow.xml
@@ -39,9 +39,9 @@
<end-state id="SubjectCanonicalizationError" />
<end-state id="InvalidCSRFToken" />
- <!-- Support for discovery implemented via branch to DoDiscovery action. -->
+ <!-- Support for discovery implemented via child flow branch to DoDiscovery action. -->
<decision-state id="DoDiscovery">
- <if test="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).getAuthenticatingAuthority() == null"
+ <if test="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).getAttemptedFlow().isDiscoveryRequired() and opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).getAuthenticatingAuthority() == null"
then="CallDiscovery"
else="PostDiscovery" />
</decision-state>
diff --git a/idp-conf/src/main/resources/system/flows/authn/external-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/external-authn-flow.xml
index 4e6461b..af53c01 100644
--- a/idp-conf/src/main/resources/system/flows/authn/external-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/external-authn-flow.xml
@@ -5,7 +5,17 @@
<!-- This is a login flow for external authentication handled outside the webflow engine. -->
- <view-state id="ExternalTransfer" view="externalRedirect:#{T(net.shibboleth.idp.authn.ExternalAuthentication).getExternalRedirect(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.External.externalAuthnPathStrategy').apply(opensamlProfileRequestContext), flowExecutionContext.getKey().toString())}">
+ <on-start>
+ <!-- If installed, this can bypass discovery. -->
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.authn.External.discoveryFunction') ? opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).setAuthenticatingAuthority(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.External.discoveryFunction').apply(opensamlProfileRequestContext)) : null" />
+ </on-start>
+
+ <action-state id="Start">
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="DoDiscovery" />
+ </action-state>
+
+ <view-state id="PostDiscovery" view="externalRedirect:#{T(net.shibboleth.idp.authn.ExternalAuthentication).getExternalRedirect(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.External.externalAuthnPathStrategy').apply(opensamlProfileRequestContext), flowExecutionContext.getKey().toString())}">
<attribute name="csrf_excluded" value="true" type="boolean"/>
<on-render>
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(calledAsExtendedFlow?:false)), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
diff --git a/idp-conf/src/main/resources/system/flows/authn/function-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/function-authn-flow.xml
index e6c4072..4a962ed 100644
--- a/idp-conf/src/main/resources/system/flows/authn/function-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/function-authn-flow.xml
@@ -5,7 +5,17 @@
<!-- This is a login flow for function-driven authentication. -->
- <action-state id="CallFunction">
+ <on-start>
+ <!-- If installed, this can bypass discovery. -->
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.authn.Function.discoveryFunction') ? opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).setAuthenticatingAuthority(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.Function.discoveryFunction').apply(opensamlProfileRequestContext)) : null" />
+ </on-start>
+
+ <action-state id="Start">
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="DoDiscovery" />
+ </action-state>
+
+ <action-state id="PostDiscovery">
<evaluate expression="ValidateFunctionResult" />
<evaluate expression="PopulateSubjectCanonicalizationContext" />
<evaluate expression="'proceed'" />
diff --git a/idp-conf/src/main/resources/system/flows/authn/mfa-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/mfa-authn-flow.xml
index 020d428..895a22d 100644
--- a/idp-conf/src/main/resources/system/flows/authn/mfa-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/mfa-authn-flow.xml
@@ -4,7 +4,17 @@
<!-- This is a login flow for executing an arbitrary multi-factor workflow consisting of other flows. -->
- <action-state id="PopulateMultiFactorAuthenticationContext">
+ <on-start>
+ <!-- If installed, this can bypass discovery. -->
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.authn.MFA.discoveryFunction') ? opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).setAuthenticatingAuthority(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.MFA.discoveryFunction').apply(opensamlProfileRequestContext)) : null" />
+ </on-start>
+
+ <action-state id="Start">
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="DoDiscovery" />
+ </action-state>
+
+ <action-state id="PostDiscovery">
<evaluate expression="PopulateMultiFactorAuthenticationContext" />
<evaluate expression="'proceed'" />
diff --git a/idp-conf/src/main/resources/system/flows/authn/remoteuser-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/remoteuser-authn-flow.xml
index c061b64..6a35d00 100644
--- a/idp-conf/src/main/resources/system/flows/authn/remoteuser-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/remoteuser-authn-flow.xml
@@ -4,8 +4,18 @@
parent="authn.abstract">
<!-- This is a login flow for container-based pseudo-authentication implemented via external authentication. -->
+
+ <on-start>
+ <!-- If installed, this can bypass discovery. -->
+ <evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.authn.RemoteUser.discoveryFunction') ? opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).setAuthenticatingAuthority(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.RemoteUser.discoveryFunction').apply(opensamlProfileRequestContext)) : null" />
+ </on-start>
+
+ <action-state id="Start">
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="DoDiscovery" />
+ </action-state>
- <view-state id="ExternalTransfer" view="externalRedirect:#{T(net.shibboleth.idp.authn.ExternalAuthentication).getExternalRedirect(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.RemoteUser.externalAuthnPathStrategy').apply(opensamlProfileRequestContext), flowExecutionContext.getKey().toString())}">
+ <view-state id="PostDiscovery" view="externalRedirect:#{T(net.shibboleth.idp.authn.ExternalAuthentication).getExternalRedirect(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.RemoteUser.externalAuthnPathStrategy').apply(opensamlProfileRequestContext), flowExecutionContext.getKey().toString())}">
<attribute name="csrf_excluded" value="true" type="boolean"/>
<on-render>
<evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).addSubcontext(new net.shibboleth.idp.authn.context.ExternalAuthenticationContext(new net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl(calledAsExtendedFlow?:false)), true).setFlowExecutionUrl(flowExecutionUrl + '&_eventId_proceed=1')" />
diff --git a/idp-conf/src/main/resources/system/flows/authn/saml-authn-flow.xml b/idp-conf/src/main/resources/system/flows/authn/saml-authn-flow.xml
index 133aa5b..ea4b579 100644
--- a/idp-conf/src/main/resources/system/flows/authn/saml-authn-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/saml-authn-flow.xml
@@ -3,17 +3,17 @@
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
parent="authn.abstract">
- <!-- This is a login flow for oroxied authentication implemented via SAML 2.0. -->
+ <!-- This is a login flow for proxied authentication implemented via SAML 2.0. -->
<on-start>
+ <!-- If installed, this can bypass discovery. -->
<evaluate expression="flowRequestContext.getActiveFlow().getApplicationContext().containsBean('shibboleth.authn.SAML.discoveryFunction') ? opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).setAuthenticatingAuthority(flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.authn.SAML.discoveryFunction').apply(opensamlProfileRequestContext)) : null" />
</on-start>
- <decision-state id="CheckDiscovery">
- <if test="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.authn.context.AuthenticationContext)).getAttemptedFlow().isDiscoveryRequired()"
- then="DoDiscovery"
- else="PostDiscovery"/>
- </decision-state>
+ <action-state id="Start">
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="DoDiscovery" />
+ </action-state>
<action-state id="PostDiscovery">
<evaluate expression="InitializeProxyProfileRequestContext" />
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list