[java-identity-provider] branch master updated: IDP-1297 - Missing qualifiers in LogoutRequest result in mismatch
Scott Cantor
cantor.2 at osu.edu
Tue Jul 24 10:12:13 EDT 2018
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=5e497a1f467afc18de5367ff1037b23cb8f95825
The following commit(s) were added to refs/heads/master by this push:
new 5e497a1 IDP-1297 - Missing qualifiers in LogoutRequest result in mismatch
5e497a1 is described below
commit 5e497a1f467afc18de5367ff1037b23cb8f95825
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jul 24 10:12:09 2018 -0400
IDP-1297 - Missing qualifiers in LogoutRequest result in mismatch
https://issues.shibboleth.net/jira/browse/IDP-1297
---
.../system/conf/relying-party-mddriven.xml | 3 +
.../QualifiedNameIDFormatsLookupFunction.java | 65 +++++++++++
.../config/SingleLogoutProfileConfiguration.java | 67 +++++++++++
.../saml2/profile/impl/ProcessLogoutRequest.java | 122 +++++++++++++++++++--
.../profile/impl/ProcessLogoutRequestTest.java | 81 +++++++++++++-
5 files changed, 329 insertions(+), 9 deletions(-)
diff --git a/idp-conf/src/main/resources/system/conf/relying-party-mddriven.xml b/idp-conf/src/main/resources/system/conf/relying-party-mddriven.xml
index 200d240..2c0b6b1 100644
--- a/idp-conf/src/main/resources/system/conf/relying-party-mddriven.xml
+++ b/idp-conf/src/main/resources/system/conf/relying-party-mddriven.xml
@@ -383,6 +383,9 @@
</constructor-arg>
</bean>
</property>
+ <property name="qualifiedNameIDFormatsLookupStrategy">
+ <bean parent="shibboleth.MDDrivenListProperty" p:propertyName="qualifiedNameIDFormats" />
+ </property>
</bean>
<bean id="SAML2.AttributeQuery.MDDriven" parent="AbstractMDDrivenSAML2Profile" lazy-init="true"
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/QualifiedNameIDFormatsLookupFunction.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/QualifiedNameIDFormatsLookupFunction.java
new file mode 100644
index 0000000..e9c5700
--- /dev/null
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/QualifiedNameIDFormatsLookupFunction.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.idp.saml.profile.config.navigate;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.annotation.Nullable;
+
+import net.shibboleth.idp.profile.config.ProfileConfiguration;
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.idp.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.saml.saml2.profile.config.SingleLogoutProfileConfiguration;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
+import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * A function that returns the {@link org.opensaml.saml.saml2.core.NameID} Formats
+ * whose NameQualifier attributes should allow for defaulting based on the result of
+ * {@link SingleLogoutProfileConfiguration#getQualifiedNameIDFormats()}
+ * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
+ * by default a child of the {@link ProfileRequestContext}.
+ *
+ * <p>If a specific setting is unavailable, no values are returned.</p>
+ *
+ * @since 3.4.0
+ */
+public class QualifiedNameIDFormatsLookupFunction extends AbstractRelyingPartyLookupFunction<Collection<String>> {
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable @NonnullElements @NotLive @Unmodifiable public Collection<String> apply(
+ @Nullable final ProfileRequestContext input) {
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc != null && pc instanceof SingleLogoutProfileConfiguration) {
+ return ImmutableList.copyOf(((SingleLogoutProfileConfiguration) pc).getQualifiedNameIDFormats());
+ }
+ }
+
+ return Collections.emptyList();
+ }
+
+}
\ No newline at end of file
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/SingleLogoutProfileConfiguration.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/SingleLogoutProfileConfiguration.java
index 93090ac..fe515f8 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/SingleLogoutProfileConfiguration.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/SingleLogoutProfileConfiguration.java
@@ -17,12 +17,22 @@
package net.shibboleth.idp.saml.saml2.profile.config;
+import java.util.Collection;
+import java.util.Collections;
+
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.profile.logic.NoConfidentialityMessageChannelPredicate;
import org.opensaml.profile.logic.NoIntegrityMessageChannelPredicate;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
/** Configuration support for SAML 2 Single Logout. */
public class SingleLogoutProfileConfiguration extends AbstractSAML2ArtifactAwareProfileConfiguration {
@@ -30,6 +40,12 @@ public class SingleLogoutProfileConfiguration extends AbstractSAML2ArtifactAware
/** ID for this profile configuration. */
public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/saml2/logout";
+ /** Lookup function to supply {@link #qualifiedNameIDFormats} property. */
+ @Nullable private Function<ProfileRequestContext,Collection<String>> qualifiedNameIDFormatsLookupStrategy;
+
+ /** NameID formats whose matching rules accomodate defaulted qualifiers. */
+ @Nonnull @NonnullElements private Collection<String> qualifiedNameIDFormats;
+
/** Constructor. */
public SingleLogoutProfileConfiguration() {
this(PROFILE_ID);
@@ -45,6 +61,57 @@ public class SingleLogoutProfileConfiguration extends AbstractSAML2ArtifactAware
setSignRequests(new NoIntegrityMessageChannelPredicate());
setSignResponses(new NoIntegrityMessageChannelPredicate());
setEncryptNameIDs(new NoConfidentialityMessageChannelPredicate());
+
+ qualifiedNameIDFormats = Collections.emptyList();
+ }
+
+ /**
+ * Get a collection of {@link org.opensaml.saml.saml2.core.NameID} Format values for which the use of
+ * the NameQualifier and SPNameQualifier attributes is defined to allow default/implicit values
+ * derived from the asserting and relying parties.
+ *
+ * <p>In the core standard, only the {@link org.opensaml.saml.saml2.core.NameIDType.PERSISTENT} and
+ * {@link org.opensaml.saml.saml2.core.NameIDType.TRANSIENT} Formats are defined in this manner. This
+ * setting identifies <strong>additional</strong> Formats that should be handled in this way.</p>
+ *
+ * @return additional Formats for which defaulting of qualifiers is permissable
+ *
+ * @since 3.4.0
+ */
+ public Collection<String> getQualifiedNameIDFormats() {
+ return ImmutableList.copyOf(getIndirectProperty(qualifiedNameIDFormatsLookupStrategy, qualifiedNameIDFormats));
}
+ /**
+ * Set a collection of {@link org.opensaml.saml.saml2.core.NameID} Format values for which the use of
+ * the NameQualifier and SPNameQualifier attributes is defined to allow default/implicit values
+ * derived from the asserting and relying parties.
+ *
+ * <p>In the core standard, only the {@link org.opensaml.saml.saml2.core.NameIDType.PERSISTENT} and
+ * {@link org.opensaml.saml.saml2.core.NameIDType.TRANSIENT} Formats are defined in this manner. This
+ * setting identifies <strong>additional</strong> Formats that should be handled in this way.</p>
+ *
+ * @param formats additional Formats for which defaulting of qualifiers is permissable
+ *
+ * @since 3.4.0
+ */
+ public void setQualifiedNameIDFormats(@Nullable @NonnullElements final Collection<String> formats) {
+ if (formats == null) {
+ qualifiedNameIDFormats = Collections.emptyList();
+ } else {
+ qualifiedNameIDFormats = StringSupport.normalizeStringCollection(formats);
+ }
+ }
+
+ /**
+ * Set a lookup strategy for the {@link #qualifiedNameIDFormats} property.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 3.4.0
+ */
+ public void setQualifiedNameIDFormatsLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,Collection<String>> strategy) {
+ qualifiedNameIDFormatsLookupStrategy = strategy;
+ }
}
\ No newline at end of file
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/ProcessLogoutRequest.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/ProcessLogoutRequest.java
index b4318f0..362bb0c 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/ProcessLogoutRequest.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/ProcessLogoutRequest.java
@@ -17,13 +17,20 @@
package net.shibboleth.idp.saml.saml2.profile.impl;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.shibboleth.idp.authn.context.SubjectContext;
import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.idp.profile.context.navigate.RelyingPartyIdLookupFunction;
+import net.shibboleth.idp.profile.context.navigate.ResponderIdLookupFunction;
+import net.shibboleth.idp.saml.profile.config.navigate.QualifiedNameIDFormatsLookupFunction;
import net.shibboleth.idp.saml.session.SAML2SPSession;
import net.shibboleth.idp.session.IdPSession;
import net.shibboleth.idp.session.SPSession;
@@ -49,6 +56,7 @@ import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
import org.opensaml.saml.common.profile.SAMLEventIds;
import org.opensaml.saml.ext.saml2aslo.Asynchronous;
import org.opensaml.saml.saml2.core.LogoutRequest;
+import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.saml.saml2.core.SessionIndex;
import org.opensaml.saml.saml2.profile.SAML2ObjectSupport;
import org.slf4j.Logger;
@@ -103,10 +111,28 @@ public class ProcessLogoutRequest extends AbstractProfileAction {
/** Lookup strategy for {@link LogoutRequest} to process. */
@Nonnull private Function<ProfileRequestContext,LogoutRequest> logoutRequestLookupStrategy;
+
+ /** Lookup strategy for obtaining qualifier-defaultable NameID Formats. */
+ @Nonnull private Function<ProfileRequestContext,Collection<String>> qualifiedNameIDFormatsLookupStrategy;
+
+ /** Optional lookup function for obtaining default NameQualifier. */
+ @Nullable private Function<ProfileRequestContext,String> assertingPartyLookupStrategy;
+
+ /** Optional lookup function for obtaining default SPNameQualifier. */
+ @Nullable private Function<ProfileRequestContext,String> relyingPartyLookupStrategy;
/** LogoutRequest to process. */
@Nullable private LogoutRequest logoutRequest;
+ /** {@link NameID} Formats allowing defaulted qualifiers. */
+ @Nonnull private Set<String> qualifiedNameIDFormats;
+
+ /** Cached lookup of assertingParty name. */
+ @Nullable private String assertingParty;
+
+ /** Cached lookup of relyingParty name. */
+ @Nullable private String relyingParty;
+
/** Constructor. */
public ProcessLogoutRequest() {
subjectContextCreationStrategy = new ChildContextLookup<>(SubjectContext.class, true);
@@ -127,6 +153,13 @@ public class ProcessLogoutRequest extends AbstractProfileAction {
logoutRequestLookupStrategy = Functions.compose(new MessageLookup<>(LogoutRequest.class),
new InboundMessageContextLookup());
+
+ qualifiedNameIDFormatsLookupStrategy = new QualifiedNameIDFormatsLookupFunction();
+
+ qualifiedNameIDFormats = Collections.emptySet();
+
+ setAssertingPartyLookupStrategy(new ResponderIdLookupFunction());
+ setRelyingPartyLookupStrategy(new RelyingPartyIdLookupFunction());
}
/**
@@ -213,6 +246,49 @@ public class ProcessLogoutRequest extends AbstractProfileAction {
logoutRequestLookupStrategy = Constraint.isNotNull(strategy, "LogoutRequest lookup strategy cannot be null");
}
+ /**
+ * Set the lookup strategy for the {@link NameID} Formats to allow defaulted qualifiers.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 3.4.0
+ */
+ public void setQualifiedNameIDFormatsLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ qualifiedNameIDFormatsLookupStrategy = Constraint.isNotNull(strategy,
+ "Qualified NameID Formats lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the lookup strategy to obtain the default IdP NameQualifier.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 3.4.0
+ */
+ public void setAssertingPartyLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,String> strategy) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ assertingPartyLookupStrategy = strategy;
+ }
+
+ /**
+ * Set the lookup strategy to obtain the default SPNameQualifier.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 3.4.0
+ */
+ public void setRelyingPartyLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,String> strategy) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ relyingPartyLookupStrategy = strategy;
+ }
+
/** {@inheritDoc} */
@Override
protected void doInitialize() throws ComponentInitializationException {
@@ -255,6 +331,8 @@ public class ProcessLogoutRequest extends AbstractProfileAction {
log.debug("{} LogoutRequest contained Asynchronous extension", getLogPrefix());
}
+ qualifiedNameIDFormats = new HashSet<>(qualifiedNameIDFormatsLookupStrategy.apply(profileRequestContext));
+
return true;
}
@@ -274,7 +352,7 @@ public class ProcessLogoutRequest extends AbstractProfileAction {
while (sessionIterator.hasNext()) {
final IdPSession session = sessionIterator.next();
- if (!sessionMatches(session)) {
+ if (!sessionMatches(profileRequestContext, session)) {
log.debug("{} IdP session {} does not contain a matching SP session", getLogPrefix(),
session.getId());
continue;
@@ -300,7 +378,7 @@ public class ProcessLogoutRequest extends AbstractProfileAction {
}
for (final SPSession spSession : session.getSPSessions()) {
- if (!sessionMatches(spSession)) {
+ if (!sessionMatches(profileRequestContext, spSession)) {
logoutCtx.getSessionMap().put(spSession.getId(), spSession);
logoutCtx.getKeyedSessionMap().put(Integer.toString(count++), spSession);
}
@@ -335,14 +413,16 @@ public class ProcessLogoutRequest extends AbstractProfileAction {
/**
* Check if the session contains a {@link SAML2SPSession} with the appropriate service ID and SessionIndex.
*
+ * @param profileRequestContext current profile request context
* @param session {@link IdPSession} to check
*
* @return true iff the set of {@link SPSession}s includes one applicable to the logout request
*/
- private boolean sessionMatches(@Nonnull final IdPSession session) {
+ private boolean sessionMatches(@Nonnull final ProfileRequestContext profileRequestContext,
+ @Nonnull final IdPSession session) {
for (final SPSession spSession : session.getSPSessions()) {
- if (sessionMatches(spSession)) {
+ if (sessionMatches(profileRequestContext, spSession)) {
return true;
}
}
@@ -353,20 +433,46 @@ public class ProcessLogoutRequest extends AbstractProfileAction {
/**
* Check if the {@link SPSession} has the appropriate service ID and SessionIndex.
*
+ * @param profileRequestContext current profile request context
* @param session {@link SPSession} to check
*
* @return true iff the {@link SPSession} directly matches the logout request
*/
- private boolean sessionMatches(@Nonnull final SPSession session) {
+ private boolean sessionMatches(@Nonnull final ProfileRequestContext profileRequestContext,
+ @Nonnull final SPSession session) {
if (session instanceof SAML2SPSession) {
final SAML2SPSession saml2Session = (SAML2SPSession) session;
+ // Make sure the SP matches.
if (!saml2Session.getId().equals(logoutRequest.getIssuer().getValue())) {
return false;
- } else if (!SAML2ObjectSupport.areNameIDsEquivalent(
- logoutRequest.getNameID(), saml2Session.getNameID())) {
+ }
+
+ // Use the format of the original NameID to determine whether to
+ // allow the qualifiers to be defaulted. If the formats don't match
+ // the eventual check will fail anyway.
+ String format = saml2Session.getNameID().getFormat();
+ if (format == null)
+ format = NameID.UNSPECIFIED;
+ if (NameID.PERSISTENT.equals(format) || NameID.TRANSIENT.equals(format)
+ || qualifiedNameIDFormats.contains(format)) {
+
+ if (assertingParty == null)
+ assertingParty = assertingPartyLookupStrategy.apply(profileRequestContext);
+ if (relyingParty == null)
+ relyingParty = relyingPartyLookupStrategy.apply(profileRequestContext);
+
+ if (!SAML2ObjectSupport.areNameIDsEquivalent(logoutRequest.getNameID(), saml2Session.getNameID(),
+ assertingParty, relyingParty)) {
+ return false;
+ }
+ } else if (!SAML2ObjectSupport.areNameIDsEquivalent(logoutRequest.getNameID(), saml2Session.getNameID())) {
return false;
- } else if (logoutRequest.getSessionIndexes().isEmpty()) {
+ }
+
+ // Check SessionIndex match.
+
+ if (logoutRequest.getSessionIndexes().isEmpty()) {
return true;
}
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/ProcessLogoutRequestTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/ProcessLogoutRequestTest.java
index 5998857..158fe8a 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/ProcessLogoutRequestTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/ProcessLogoutRequestTest.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.saml.saml2.profile.impl;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -25,8 +26,10 @@ import javax.servlet.http.Cookie;
import net.shibboleth.idp.authn.context.SubjectContext;
import net.shibboleth.idp.profile.ActionTestingSupport;
import net.shibboleth.idp.profile.RequestContextBuilder;
+import net.shibboleth.idp.profile.config.ProfileConfiguration;
import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
import net.shibboleth.idp.saml.saml2.profile.SAML2ActionTestingSupport;
+import net.shibboleth.idp.saml.saml2.profile.config.SingleLogoutProfileConfiguration;
import net.shibboleth.idp.saml.session.SAML1SPSession;
import net.shibboleth.idp.saml.session.SAML2SPSession;
import net.shibboleth.idp.saml.session.impl.SAML1SPSessionSerializer;
@@ -78,7 +81,11 @@ public class ProcessLogoutRequestTest extends SessionManagerBaseTestCase {
XMLObjectProviderRegistrySupport.getBuilderFactory().<SessionIndex>getBuilderOrThrow(
SessionIndex.DEFAULT_ELEMENT_NAME);
- src = new RequestContextBuilder().buildRequestContext();
+ final SingleLogoutProfileConfiguration logoutConfig = new SingleLogoutProfileConfiguration();
+ logoutConfig.setQualifiedNameIDFormats(Collections.singletonList(NameID.UNSPECIFIED));
+ src = new RequestContextBuilder().setRelyingPartyProfileConfigurations(
+ Collections.<ProfileConfiguration>singletonList(logoutConfig)).buildRequestContext();
+
prc = new WebflowRequestContextProfileRequestContextLookup().apply(src);
action = new ProcessLogoutRequest();
@@ -173,6 +180,78 @@ public class ProcessLogoutRequestTest extends SessionManagerBaseTestCase {
sessionManager.destroySession(session.getId(), false);
}
+ @Test public void testDefaultedRequestQualifiers() throws SessionException, ResolverException {
+ final Cookie cookie = createSession("joe");
+
+ final NameID nameId = SAML2ActionTestingSupport.buildNameID("joe");
+ nameId.setNameQualifier(ActionTestingSupport.OUTBOUND_MSG_ISSUER);
+ nameId.setSPNameQualifier(ActionTestingSupport.INBOUND_MSG_ISSUER);
+ prc.getInboundMessageContext().setMessage(SAML2ActionTestingSupport.buildLogoutRequest(nameId));
+
+ HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
+ ((MockHttpServletRequest) HttpServletRequestResponseContext.getRequest()).setCookies(cookie);
+
+ final long creation = System.currentTimeMillis();
+ final long expiration = creation + 3600 * 60 * 1000;
+
+ final IdPSession session = sessionManager.resolveSingle(new CriteriaSet(new HttpServletRequestCriterion()));
+ Assert.assertNotNull(session);
+ final NameID nameIdForSession = SAML2ActionTestingSupport.buildNameID("joe");
+ session.addSPSession(new SAML2SPSession(ActionTestingSupport.INBOUND_MSG_ISSUER, creation, expiration,
+ nameIdForSession, "index"));
+
+ final Event event = action.execute(src);
+ ActionTestingSupport.assertProceedEvent(event);
+ final SubjectContext subjectCtx = prc.getSubcontext(SubjectContext.class);
+ Assert.assertNotNull(subjectCtx);
+ Assert.assertEquals(subjectCtx.getPrincipalName(), "joe");
+
+ final SessionContext sessionCtx = prc.getSubcontext(SessionContext.class);
+ Assert.assertNotNull(sessionCtx);
+ Assert.assertEquals(session.getId(), sessionCtx.getIdPSession().getId());
+
+ final LogoutContext logoutCtx = prc.getSubcontext(LogoutContext.class);
+ if (logoutCtx != null) {
+ Assert.assertEquals(logoutCtx.getSessionMap().size(), 0);
+ }
+ }
+
+ @Test public void testDefaultedSessionQualifiers() throws SessionException, ResolverException {
+ final Cookie cookie = createSession("joe");
+
+ final NameID nameId = SAML2ActionTestingSupport.buildNameID("joe");
+ prc.getInboundMessageContext().setMessage(SAML2ActionTestingSupport.buildLogoutRequest(nameId));
+
+ HttpServletRequestResponseContext.loadCurrent(new MockHttpServletRequest(), new MockHttpServletResponse());
+ ((MockHttpServletRequest) HttpServletRequestResponseContext.getRequest()).setCookies(cookie);
+
+ final long creation = System.currentTimeMillis();
+ final long expiration = creation + 3600 * 60 * 1000;
+
+ final IdPSession session = sessionManager.resolveSingle(new CriteriaSet(new HttpServletRequestCriterion()));
+ Assert.assertNotNull(session);
+ final NameID nameIdForSession = SAML2ActionTestingSupport.buildNameID("joe");
+ nameIdForSession.setNameQualifier(ActionTestingSupport.OUTBOUND_MSG_ISSUER);
+ nameIdForSession.setSPNameQualifier(ActionTestingSupport.INBOUND_MSG_ISSUER);
+ session.addSPSession(new SAML2SPSession(ActionTestingSupport.INBOUND_MSG_ISSUER, creation, expiration,
+ nameIdForSession, "index"));
+
+ final Event event = action.execute(src);
+ ActionTestingSupport.assertProceedEvent(event);
+ final SubjectContext subjectCtx = prc.getSubcontext(SubjectContext.class);
+ Assert.assertNotNull(subjectCtx);
+ Assert.assertEquals(subjectCtx.getPrincipalName(), "joe");
+
+ final SessionContext sessionCtx = prc.getSubcontext(SessionContext.class);
+ Assert.assertNotNull(sessionCtx);
+ Assert.assertEquals(session.getId(), sessionCtx.getIdPSession().getId());
+
+ final LogoutContext logoutCtx = prc.getSubcontext(LogoutContext.class);
+ if (logoutCtx != null) {
+ Assert.assertEquals(logoutCtx.getSessionMap().size(), 0);
+ }
+ }
+
@Test public void testSessionOneSPSession() throws SessionException, ResolverException {
final Cookie cookie = createSession("joe");
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list