[java-plugin-shibd] branch main updated: Untested discovery initiator flow.
Scott Cantor
cantor.2 at osu.edu
Fri Jun 27 20:07:17 UTC 2025
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-plugin-shibd.
View the commit online:
http://git.shibboleth.net/view/?p=java-plugin-shibd.git;a=commit;h=6f5a59e406bd73599136522cc8e95f230d023499
The following commit(s) were added to refs/heads/main by this push:
new 6f5a59e Untested discovery initiator flow.
6f5a59e is described below
commit 6f5a59e406bd73599136522cc8e95f230d023499
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Jun 27 16:07:10 2025 -0400
Untested discovery initiator flow.
---
.../idp/flows/sp/initiator/disco/disco-beans.xml | 25 +++
.../idp/flows/sp/initiator/disco/disco-flow.xml | 20 ++
.../shibboleth/sp/profile/InitiatorConstants.java | 6 +-
.../sp/profile/impl/IssueDiscoveryRequest.java | 238 +++++++++++++++++++++
.../impl/ValidateSessionInitiatorRequest.java | 49 ++++-
.../impl/ValidateSessionInitiatorRequestTest.java | 75 +++++--
6 files changed, 381 insertions(+), 32 deletions(-)
diff --git a/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-beans.xml b/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-beans.xml
new file mode 100644
index 0000000..9a68c38
--- /dev/null
+++ b/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-beans.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize" default-destroy-method="destroy">
+
+ <util:constant id="shiibboleth.sp.ProfileId"
+ static-field="net.shibboleth.saml.saml2.profile.config.BrowserSSOProfileConfiguration.PROFILE_ID" />
+
+ <import resource="classpath:/META-INF/net/shibboleth/idp/flows/sp/saml2-common-beans.xml" />
+
+ <bean id="ValidateSessionInitiatorRequest"
+ class="net.shibboleth.sp.profile.impl.ValidateSessionInitiatorRequest" scope="prototype"
+ p:setRequireDiscoveryURL="true"
+ p:setRequireRelyingPartyId="false" />
+
+ <bean id="IssueDiscoveryRequest"
+ class="net.shibboleth.sp.profile.impl.IssueDiscoveryRequest" scope="prototype"
+ p:httpServletResponseSupplier-ref="shibboleth.RemotedHttpServletResponseSupplier" />
+
+
+</beans>
diff --git a/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-flow.xml b/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-flow.xml
new file mode 100644
index 0000000..e3d0241
--- /dev/null
+++ b/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-flow.xml
@@ -0,0 +1,20 @@
+<flow xmlns="http://www.springframework.org/schema/webflow"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
+ parent="sp/initiator">
+
+ <action-state id="DiscoverySessionInitiator">
+ <evaluate expression="ValidateSessionInitiatorRequest" />
+ <evaluate expression="IssueDiscoveryRequest" />
+
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="proceed" />
+ <!-- Remap any other events into a fall-through to the next flow. -->
+ <transition to="ReselectFlow" />
+ </action-state>
+
+ <!-- The file really exists in this directory, but it's referenced from extending flow-directories -->
+ <bean-import resource="classpath:/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-beans.xml" />
+
+</flow>
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/profile/InitiatorConstants.java b/sp-server-api/src/main/java/net/shibboleth/sp/profile/InitiatorConstants.java
index a3d4f76..db5b868 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/profile/InitiatorConstants.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/profile/InitiatorConstants.java
@@ -29,10 +29,10 @@ public final class InitiatorConstants {
/** Legacy entityID input parameter. */
@Nonnull @NotEmpty public static final String ENTITY_ID = "entityID";
- /** Handler input parameter. */
- @Nonnull @NotEmpty public static final String HANDLER = "handler";
+ /** Discovery response/return URL input parameter. */
+ @Nonnull @NotEmpty public static final String DISCOVERY_RETURN_URL = "disco_return_url";
- /** Response URL input structure. */
+ /** Response URL input value or structure. */
@Nonnull @NotEmpty public static final String RESPONSE_URL = "response_url";
/** Private constructor. */
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequest.java b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequest.java
new file mode 100644
index 0000000..629d3c6
--- /dev/null
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequest.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.profile.impl;
+
+import java.io.IOException;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import com.google.common.escape.Escaper;
+import com.google.common.net.UrlEscapers;
+
+import net.shibboleth.profile.relyingparty.RelyingPartyConfiguration;
+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 net.shibboleth.shared.resolver.ResolverException;
+import net.shibboleth.sp.ddf.DDF;
+import net.shibboleth.sp.messaging.RemotedHttpServletRequestResponseContext;
+import net.shibboleth.sp.profile.AbstractApplicationAction;
+import net.shibboleth.sp.profile.InitiatorConstants;
+import net.shibboleth.sp.profile.SPConstants;
+
+/**
+ * Generates a request to a discovery service per the protocol defined originally by us under
+ * the SAML TC at OASIS.
+ *
+ * <p>While referred to as a "SAML" discovery mechanism, it is not SAML-specific or SAML-aware
+ * in any real sense and is just a generic, insecure, redirect-based mechanism to ask a web site
+ * to return a named parameter to a designated return location.</p>
+ *
+ * @pre The input message has been validated to ensure a {@link InitiatorConstants#DISCOVERY_RETURN_URL}
+ * parameter is present.
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_MESSAGE}
+ * @event {@link EventIds#MESSAGE_PROC_ERROR}
+ */
+public class IssueDiscoveryRequest extends AbstractApplicationAction {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(IssueDiscoveryRequest.class);
+
+ /** Strategy used to obtain the discovery URL. */
+ @NonnullAfterInit private Function<ProfileRequestContext,String> discoveryURLLookupStrategy;
+
+ /** Strategy used to obtain the request issuer value. */
+ @Nonnull private Function<ProfileRequestContext,String> issuerLookupStrategy;
+
+ /** Condition to evaluate to determine passive use. */
+ @Nonnull private Predicate<ProfileRequestContext> passiveCondition;
+
+ /** Input message. */
+ @NonnullBeforeExec private DDF input;
+
+ /** The discovery URL to use. */
+ @NonnullBeforeExec private String discoveryURL;
+
+ /** Value for "entityID" paremeter in request. */
+ @NonnullBeforeExec private String issuer;
+
+ /** The agent handler URL to return control to. */
+ @NonnullBeforeExec private String returnURL;
+
+ /** State token. */
+ @Nullable private String state;
+
+ /** Constructor. */
+ public IssueDiscoveryRequest() {
+ issuerLookupStrategy = new ApplicationDefaultIssuerStrategy();
+ passiveCondition = new DefaultPassiveCondition();
+ }
+
+ /**
+ * Set the strategy used to obtain the discovery URL.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setDiscoveryURLLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ checkSetterPreconditions();
+ discoveryURLLookupStrategy = Constraint.isNotNull(strategy, "Discovery URL lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the strategy used to locate the issuer value to use.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setIssuerLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+ checkSetterPreconditions();
+ issuerLookupStrategy = Constraint.isNotNull(strategy, "Issuer lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (discoveryURLLookupStrategy == null) {
+ throw new ComponentInitializationException("Discovery URL lookup strategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ discoveryURL = discoveryURLLookupStrategy.apply(profileRequestContext);
+ if (discoveryURL == null) {
+ log.error("{} Unable to obtain discovery URL for request", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.MESSAGE_PROC_ERROR);
+ return false;
+ }
+
+ issuer = issuerLookupStrategy.apply(profileRequestContext);
+ if (issuer == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.MESSAGE_PROC_ERROR);
+ log.error("{} Unable to obtain entityID parameter value for discovery request", getLogPrefix());
+ return false;
+ }
+
+ input = ensureAgentRequestContext().getInput();
+ if (input == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+ log.error("{} No input message from agent", getLogPrefix());
+ return false;
+ }
+
+ state = input.getmember(SPConstants.STATE).string();
+
+ // This is checked earlier in the flow, so can be treated as an outright error here.
+ returnURL = input.getmember(InitiatorConstants.DISCOVERY_RETURN_URL).string();
+ if (returnURL == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+ log.error("{} No '{}' input parameter from agent", getLogPrefix(), InitiatorConstants.DISCOVERY_RETURN_URL);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ // We have to add the state parameter (usually placed there by our calling flow) to the query
+ // string of the already-URL-encoded return URL. We URL-encode the character sequence
+ // "&state=<value>" and append that to the existing URL. This ensures the agent will get our
+ // state token back from the DS to provide to us afterwards.
+
+ final Escaper escaper = UrlEscapers.urlFormParameterEscaper();
+ if (state != null) {
+ returnURL += escaper.escape('&' + SPConstants.STATE + '=' + state);
+ // At this point, discoveryURL is already encoded, and thus does not need to
+ // be run through the encoder, which is done this way to ensure that the character set
+ // of this URL is arbitrary from the hub's perspective, to avoid requiiring an explicit
+ // conversion into String, that would depend on charset, This is the essence of the web's
+ // brokenness, that URLs are not in a defined or even *knowable* character encoding
+ // (as only the *body* is covered by the headers sent with the request).
+ }
+
+ discoveryURL += (discoveryURL.indexOf('?') > 0 ? '&' : '?') + "return=" + returnURL
+ + "&entityID=" + escaper.escape(issuer);
+ if (passiveCondition.test(profileRequestContext)) {
+ discoveryURL += "&isPassive=1";
+ }
+
+ // Issue a redirect while the remoted layer is loaded in.
+ try {
+ RemotedHttpServletRequestResponseContext.loadCurrent(null,
+ ensureAgentRequestContext().getRemotedHttpServletResponse());
+ ensureHttpServletResponse().sendRedirect(discoveryURL);
+ } catch (final IOException e) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
+ log.error("{} I/O error issuing remoted discovery redirect", getLogPrefix(), e);
+ } finally {
+ RemotedHttpServletRequestResponseContext.clearCurrent();
+ }
+ }
+
+ /**
+ * Derives issuer value from application layer's default settings.
+ */
+ private class ApplicationDefaultIssuerStrategy implements Function<ProfileRequestContext,String> {
+
+ /** {@inheritDoc} */
+ @Nullable public String apply(@Nullable final ProfileRequestContext input) {
+
+ try {
+ final RelyingPartyConfiguration rpConfig = ensureApplication().resolveSingle(null);
+ if (rpConfig != null) {
+ return rpConfig.getIssuer(input);
+ }
+ } catch (final ResolverException e) {
+ log.error("{} Error resolving RelyingPartyConfiguration", getLogPrefix(), e);
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Default predicate aware of the two "known" protocols, would have to override for others.
+ */
+ private class DefaultPassiveCondition implements Predicate<ProfileRequestContext> {
+
+ /** {@inheritDoc} */
+ public boolean test(@Nullable final ProfileRequestContext t) {
+ return input.getmember("isPassive").integer() == 1
+ && "none".equals(input.getmember("prompt").string());
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/ValidateSessionInitiatorRequest.java b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/ValidateSessionInitiatorRequest.java
index b8fa767..01745cb 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/ValidateSessionInitiatorRequest.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/ValidateSessionInitiatorRequest.java
@@ -25,6 +25,7 @@ import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
import net.shibboleth.sp.Application;
import net.shibboleth.sp.ddf.DDF;
import net.shibboleth.sp.profile.AbstractApplicationAction;
@@ -35,8 +36,8 @@ import net.shibboleth.shared.logic.Constraint;
/**
* Initiating action of a typical Session Initiator flow, this validates the input message for
- * correctness, and then creates a {@link RelyingPartyContext} based on the identity of the
- * eventual authenticating authority (the IdP/OP/etc.).
+ * correctness, and may create a {@link RelyingPartyContext} based on the identity of the
+ * eventual authenticating authority (the IdP/OP/etc.) if this is part of the request.
*
* <p>The authority ID is potentially supplied by the agent in the request, or may be defaulted
* based on the {@link Application}.</p>
@@ -63,13 +64,15 @@ public class ValidateSessionInitiatorRequest extends AbstractApplicationAction {
/** Whether to require a relying party ID to exist. */
private boolean requireRelyingPartyId;
+ /** Whether to require a discovery URL input parameter. */
+ private boolean requireDiscoveryURL;
+
/** The relying party name to base the inbound context on. */
@Nullable private String relyingPartyId;
/** Constructor. */
public ValidateSessionInitiatorRequest() {
relyingPartyContextCreationStrategy = new ChildContextLookup<>(RelyingPartyContext.class, true);
- requireRelyingPartyId = true;
}
/**
@@ -99,6 +102,17 @@ public class ValidateSessionInitiatorRequest extends AbstractApplicationAction {
requireRelyingPartyId = flag;
}
+ /**
+ * Sets whether to require {@link InitiatorConstants#DISCOVERY_RETURN_URL} input parameter.
+ *
+ * @param flag flag to set
+ */
+ public void setRequireDiscoveryURL(final boolean flag) {
+ checkSetterPreconditions();
+
+ requireDiscoveryURL = flag;
+ }
+
/** {@inheritDoc} */
@Override
protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -114,6 +128,14 @@ public class ValidateSessionInitiatorRequest extends AbstractApplicationAction {
return false;
}
+ if (requireDiscoveryURL) {
+ if (StringSupport.trimOrNull(input.getmember(InitiatorConstants.DISCOVERY_RETURN_URL).string()) == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+ log.info("{} Input message did not include '{}' parameter", getLogPrefix(), InitiatorConstants.DISCOVERY_RETURN_URL);
+ return false;
+ }
+ }
+
relyingPartyId = input.getmember(InitiatorConstants.AUTHORITY).string();
if (relyingPartyId == null) {
relyingPartyId = input.getmember(InitiatorConstants.ENTITY_ID).string();
@@ -123,14 +145,25 @@ public class ValidateSessionInitiatorRequest extends AbstractApplicationAction {
getLogPrefix());
relyingPartyId = ensureApplication().getAuthenticatingAuthority(profileRequestContext);
}
-
- if (relyingPartyId == null && requireRelyingPartyId) {
+
+ if (requireRelyingPartyId) {
+ // Need it, don't have it, signal an error to drop into discovery (if configured).
+ if (relyingPartyId == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+ log.debug("{} Authenticating authority unknown", getLogPrefix());
+ return false;
+ }
+ // Need it, got it, good.
+ return true;
+ } else if (relyingPartyId != null) {
+ // We don't need it, but it's there? We shouldn't be running, because a loop could result.
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
- log.error("{} Authenticating authority unknown", getLogPrefix());
+ log.warn("{} Authenticating authority provided, but not expected", getLogPrefix());
+ return false;
+ } else {
+ // Don't need it, don't have it, skip execution phase.
return false;
}
-
- return true;
}
/** {@inheritDoc} */
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/ValidateSessionInitiatorRequestTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/ValidateSessionInitiatorRequestTest.java
index a545c97..5e3073f 100644
--- a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/ValidateSessionInitiatorRequestTest.java
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/ValidateSessionInitiatorRequestTest.java
@@ -23,6 +23,9 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.escape.Escaper;
+import com.google.common.net.UrlEscapers;
+
import net.shibboleth.idp.profile.testing.ActionTestingSupport;
import net.shibboleth.profile.context.RelyingPartyContext;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -40,7 +43,7 @@ public class ValidateSessionInitiatorRequestTest extends BaseAgplicationActionTe
@Nonnull @NotEmpty private final static String TEST_VALUE = "https://idp.example.org";
private ValidateSessionInitiatorRequest action;
-
+
/**
* Set up test.
*
@@ -49,11 +52,7 @@ public class ValidateSessionInitiatorRequestTest extends BaseAgplicationActionTe
@BeforeMethod
public void setUp() throws ComponentInitializationException {
super.beforeMethod();
-
prc.removeSubcontext(RelyingPartyContext.class);
-
- action = new ValidateSessionInitiatorRequest();
- action.initialize();
}
/**
@@ -62,17 +61,22 @@ public class ValidateSessionInitiatorRequestTest extends BaseAgplicationActionTe
@AfterMethod
public void tearDown() {
action.destroy();
+ action = null;
}
@Test
- public void testNoInput() {
+ public void testNoInput() throws ComponentInitializationException {
+ createAction(false, false);
+
final Event event = action.execute(src);
ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
Assert.assertNull(prc.getSubcontext(RelyingPartyContext.class));
}
@Test
- public void testNoResponseURL() {
+ public void testNoHandlerWhenRequired() throws ComponentInitializationException {
+ createAction(false, true);
+
final DDF input = new DDF(null).structure();
arc.setInput(input);
@@ -82,9 +86,25 @@ public class ValidateSessionInitiatorRequestTest extends BaseAgplicationActionTe
}
@Test
- public void testNoAuthorityWhenRequired() {
+ public void testHandlerWhenRequired() throws ComponentInitializationException {
+ createAction(false, true);
+
+ final Escaper escaper = UrlEscapers.urlFormParameterEscaper();
+
+ final DDF input = new DDF(null).structure();
+ input.addmember(InitiatorConstants.DISCOVERY_RETURN_URL).string(escaper.escape("https://sp.example.org/handler?DS=1"));
+ arc.setInput(input);
+
+ final Event event = action.execute(src);
+ ActionTestingSupport.assertProceedEvent(event);
+ Assert.assertNull(prc.getSubcontext(RelyingPartyContext.class));
+ }
+
+ @Test
+ public void testNoAuthorityWhenRequired() throws ComponentInitializationException {
+ createAction(true, false);
+
final DDF input = new DDF(null).structure();
- input.addmember(InitiatorConstants.RESPONSE_URL).string("foo");
arc.setInput(input);
final Event event = action.execute(src);
@@ -94,28 +114,24 @@ public class ValidateSessionInitiatorRequestTest extends BaseAgplicationActionTe
@Test
public void testNoAuthorityWhenNotRequired() throws ComponentInitializationException {
- action = new ValidateSessionInitiatorRequest();
- action.setRequireRelyingPartyId(false);
- action.initialize();
-
+ createAction(false, false);
+
final DDF input = new DDF(null).structure();
- input.addmember(InitiatorConstants.RESPONSE_URL).string("foo");
arc.setInput(input);
final Event event = action.execute(src);
ActionTestingSupport.assertProceedEvent(event);
- final RelyingPartyContext rpc = prc.getSubcontext(RelyingPartyContext.class);
- assert rpc != null;
- Assert.assertNull(rpc.getRelyingPartyId());
+ Assert.assertNull(prc.getSubcontext(RelyingPartyContext.class));
}
@Test
- public void testFallbackAuthority() {
+ public void testFallbackAuthority() throws ComponentInitializationException {
+ createAction(true, false);
+
application.setAuthenticatingAuthority(TEST_VALUE);
final DDF input = new DDF(null).structure();
- input.addmember(InitiatorConstants.RESPONSE_URL).string("foo");
arc.setInput(input);
final Event event = action.execute(src);
@@ -127,10 +143,11 @@ public class ValidateSessionInitiatorRequestTest extends BaseAgplicationActionTe
}
@Test
- public void testInputAuthority() {
+ public void testInputAuthority() throws ComponentInitializationException {
+ createAction(true, false);
+
application.setAuthenticatingAuthority(TEST_VALUE);
final DDF input = new DDF(null).structure();
- input.addmember(InitiatorConstants.RESPONSE_URL).string("foo");
input.addmember(InitiatorConstants.AUTHORITY).string(TEST_VALUE + "/shibboleth");
arc.setInput(input);
@@ -142,4 +159,20 @@ public class ValidateSessionInitiatorRequestTest extends BaseAgplicationActionTe
Assert.assertEquals(rpc.getRelyingPartyId(), TEST_VALUE + "/shibboleth");
}
+ /**
+ * Create action with the specified behavior.
+ *
+ * @param requireAuthority
+ * @param requireDisco
+ *
+ * @throws ComponentInitializationException
+ */
+ private void createAction(final boolean requireAuthority, final boolean requireDisco)
+ throws ComponentInitializationException {
+ action = new ValidateSessionInitiatorRequest();
+ action.setRequireRelyingPartyId(requireAuthority);
+ action.setRequireDiscoveryURL(requireDisco);
+ action.initialize();
+ }
+
}
\ 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