[java-identity-provider] branch main updated: IDP-2251 - Map OIDC ACRs to SAML AC classes in proxied authentication
Scott Cantor
cantor.2 at osu.edu
Thu Feb 22 17:15:36 UTC 2024
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=289804f64bc5fcc979ee5d11e911ab1ee9de5a66
The following commit(s) were added to refs/heads/main by this push:
new 289804f64 IDP-2251 - Map OIDC ACRs to SAML AC classes in proxied authentication
289804f64 is described below
commit 289804f64bc5fcc979ee5d11e911ab1ee9de5a66
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Feb 22 12:15:32 2024 -0500
IDP-2251 - Map OIDC ACRs to SAML AC classes in proxied authentication
https://shibboleth.atlassian.net/browse/IDP-2251
Cleaned up Principal typing issues in profile configs.
Adjusted typing of ProxyAware strategy for auth methods.
Added property to allow mapping any unknown Principals into class refs.
---
.../idp/cas/config/LoginConfiguration.java | 13 +++--
.../idp/flows/authn/saml-authn-beans.xml | 1 +
...DefaultAuthenticationMethodsLookupFunction.java | 7 +--
.../impl/BrowserSSOProfileConfiguration.java | 12 ++---
.../impl/BrowserSSOProfileConfiguration.java | 8 +--
.../saml/saml2/profile/impl/AddAuthnRequest.java | 46 +++++++++++++++-
.../impl/BrowserSSOProfileConfigurationTest.java | 5 +-
.../impl/BrowserSSOProfileConfigurationTest.java | 5 +-
...ultAuthenticationMethodsLookupFunctionTest.java | 16 +++---
.../saml2/profile/impl/AddAuthnRequestTest.java | 63 ++++++++++++++++++++--
10 files changed, 138 insertions(+), 38 deletions(-)
diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
index 91699d212..65073026e 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
@@ -27,7 +27,6 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
-import net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal;
import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NonNegative;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -39,7 +38,6 @@ import net.shibboleth.shared.logic.FunctionSupport;
import net.shibboleth.shared.logic.PredicateSupport;
import net.shibboleth.shared.primitive.StringSupport;
-
/**
* CAS protocol configuration that applies to the <code>/login</code> URI.
*
@@ -67,7 +65,7 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
@Nonnull private Function<ProfileRequestContext,Collection<String>> postAuthenticationFlowsLookupStrategy;
/** Lookup function to supply defaultAuthenticationContexts property. */
- @Nonnull private Function<ProfileRequestContext,Collection<AuthnContextClassRefPrincipal>>
+ @Nonnull private Function<ProfileRequestContext,Collection<Principal>>
defaultAuthenticationContextsLookupStrategy;
/** Whether to mandate forced authentication for the request. */
@@ -94,7 +92,7 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
/** {@inheritDoc} */
@Nonnull @NotLive @Unmodifiable public List<Principal> getDefaultAuthenticationMethods(
@Nullable final ProfileRequestContext profileRequestContext) {
- final Collection<AuthnContextClassRefPrincipal> methods =
+ final Collection<Principal> methods =
defaultAuthenticationContextsLookupStrategy.apply(profileRequestContext);
if (methods != null) {
return CollectionSupport.copyToList(methods);
@@ -107,9 +105,10 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
*
* @param contexts default authentication contexts to use
*/
- public void setDefaultAuthenticationMethods(@Nullable final Collection<AuthnContextClassRefPrincipal> contexts) {
+ public void setDefaultAuthenticationMethods(@Nullable final Collection<Principal> contexts) {
if (contexts != null) {
- defaultAuthenticationContextsLookupStrategy = FunctionSupport.constant(List.copyOf(contexts));
+ defaultAuthenticationContextsLookupStrategy =
+ FunctionSupport.constant(CollectionSupport.copyToList(contexts));
} else {
defaultAuthenticationContextsLookupStrategy = FunctionSupport.constant(null);
}
@@ -121,7 +120,7 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
* @param strategy lookup strategy
*/
public void setDefaultAuthenticationMethodsLookupStrategy(
- @Nonnull final Function<ProfileRequestContext,Collection<AuthnContextClassRefPrincipal>> strategy) {
+ @Nonnull final Function<ProfileRequestContext,Collection<Principal>> strategy) {
defaultAuthenticationContextsLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
}
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
index 277e3e92b..10677f3c3 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
@@ -150,6 +150,7 @@
class="net.shibboleth.idp.saml.saml2.profile.impl.AddAuthnRequest" scope="prototype"
p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
p:overwriteExisting="true"
+ p:convertUnknownRequestedPrincipals="%{idp.authn.SAML.convertUnknownRequestedPrincipals:false}"
p:issuerLookupStrategy-ref="shibboleth.IssuerLookup.Simple"
p:nameIDLookupStrategy="#{getObject('%{idp.authn.SAML.NameIDLookupStrategy:}'.trim())}">
<property name="identifierGeneratorLookupStrategy">
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyAwareDefaultAuthenticationMethodsLookupFunction.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyAwareDefaultAuthenticationMethodsLookupFunction.java
index fd58aee14..5b114edd1 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyAwareDefaultAuthenticationMethodsLookupFunction.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyAwareDefaultAuthenticationMethodsLookupFunction.java
@@ -30,7 +30,6 @@ import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.authn.context.RequestedPrincipalContext;
-import net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal;
import net.shibboleth.shared.annotation.constraint.NotLive;
import net.shibboleth.shared.annotation.constraint.Unmodifiable;
import net.shibboleth.shared.collection.CollectionSupport;
@@ -50,7 +49,7 @@ import net.shibboleth.shared.collection.CollectionSupport;
* @since 4.0.0
*/
public class ProxyAwareDefaultAuthenticationMethodsLookupFunction
- implements Function<ProfileRequestContext,Collection<AuthnContextClassRefPrincipal>> {
+ implements Function<ProfileRequestContext,Collection<Principal>> {
/** Mappings to transform proxied Principals. */
@Nonnull private Map<Principal,Collection<Principal>> principalMappings;
@@ -78,7 +77,7 @@ public class ProxyAwareDefaultAuthenticationMethodsLookupFunction
}
/** {@inheritDoc} */
- @Nonnull @Unmodifiable @NotLive public Collection<AuthnContextClassRefPrincipal> apply(
+ @Nonnull @Unmodifiable @NotLive public Collection<Principal> apply(
@Nullable final ProfileRequestContext input) {
if (input != null) {
final BaseContext parent = input.getParent();
@@ -95,8 +94,6 @@ public class ProxyAwareDefaultAuthenticationMethodsLookupFunction
return CollectionSupport.singletonList(p);
})
.flatMap(Collection::stream)
- .filter(AuthnContextClassRefPrincipal.class::isInstance)
- .map(AuthnContextClassRefPrincipal.class::cast)
.collect(CollectionSupport.nonnullCollector(Collectors.toUnmodifiableList())).get();
}
}
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
index 4665ef173..8674f9c84 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
@@ -27,7 +27,6 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
-import net.shibboleth.idp.saml.authn.principal.AuthenticationMethodPrincipal;
import net.shibboleth.profile.config.AttributeResolvingProfileConfiguration;
import net.shibboleth.saml.profile.config.SAMLAssertionProducingProfileConfiguration;
import net.shibboleth.shared.annotation.constraint.NonNegative;
@@ -60,7 +59,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
@Nonnull private Predicate<ProfileRequestContext> forceAuthnPredicate;
/** Lookup function to supply default authentication methods. */
- @Nonnull private Function<ProfileRequestContext,Collection<AuthenticationMethodPrincipal>>
+ @Nonnull private Function<ProfileRequestContext,Collection<Principal>>
defaultAuthenticationMethodsLookupStrategy;
/** Lookup function to supply authentication flows. */
@@ -172,7 +171,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
/** {@inheritDoc} */
@Nonnull @NotLive @Unmodifiable public List<Principal> getDefaultAuthenticationMethods(
@Nullable final ProfileRequestContext profileRequestContext) {
- final Collection<AuthenticationMethodPrincipal> methods =
+ final Collection<Principal> methods =
defaultAuthenticationMethodsLookupStrategy.apply(profileRequestContext);
if (methods != null) {
return CollectionSupport.copyToList(methods);
@@ -185,10 +184,11 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
*
* @param methods default authentication methods to use
*/
- public void setDefaultAuthenticationMethods(@Nullable final Collection<AuthenticationMethodPrincipal> methods) {
+ public void setDefaultAuthenticationMethods(@Nullable final Collection<Principal> methods) {
if (methods != null) {
- defaultAuthenticationMethodsLookupStrategy = FunctionSupport.constant(List.copyOf(methods));
+ defaultAuthenticationMethodsLookupStrategy =
+ FunctionSupport.constant(CollectionSupport.copyToList(methods));
} else {
defaultAuthenticationMethodsLookupStrategy = FunctionSupport.constant(null);
}
@@ -202,7 +202,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
* @since 3.3.0
*/
public void setDefaultAuthenticationMethodsLookupStrategy(
- @Nonnull final Function<ProfileRequestContext,Collection<AuthenticationMethodPrincipal>> strategy) {
+ @Nonnull final Function<ProfileRequestContext,Collection<Principal>> strategy) {
defaultAuthenticationMethodsLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
}
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
index 4e5440463..711712148 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
@@ -125,7 +125,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
@Nonnull private Function<ProfileRequestContext,String> authnContextComparisonLookupStrategy;
/** Lookup function to supply default authentication methods. */
- @Nonnull private Function<ProfileRequestContext,Collection<AuthnContextClassRefPrincipal>>
+ @Nonnull private Function<ProfileRequestContext,Collection<Principal>>
defaultAuthenticationContextsLookupStrategy;
/** Lookup function to supply authentication flows. */
@@ -815,7 +815,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
/** {@inheritDoc} */
@Nonnull @NotLive @Unmodifiable public List<Principal> getDefaultAuthenticationMethods(
@Nullable final ProfileRequestContext profileRequestContext) {
- final Collection<AuthnContextClassRefPrincipal> methods =
+ final Collection<Principal> methods =
defaultAuthenticationContextsLookupStrategy.apply(profileRequestContext);
if (methods != null) {
return CollectionSupport.copyToList(methods);
@@ -829,7 +829,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
* @param contexts default authentication contexts to use
*/
public void setDefaultAuthenticationMethods(
- @Nullable final Collection<AuthnContextClassRefPrincipal> contexts) {
+ @Nullable final Collection<Principal> contexts) {
if (contexts != null) {
defaultAuthenticationContextsLookupStrategy = FunctionSupport.constant(List.copyOf(contexts));
} else {
@@ -845,7 +845,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
* @since 3.3.0
*/
public void setDefaultAuthenticationMethodsLookupStrategy(
- @Nonnull final Function<ProfileRequestContext,Collection<AuthnContextClassRefPrincipal>> strategy) {
+ @Nonnull final Function<ProfileRequestContext,Collection<Principal>> strategy) {
defaultAuthenticationContextsLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
}
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
index d476c9e23..81bdddc12 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
@@ -55,6 +55,7 @@ import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
import org.opensaml.saml.common.SAMLObjectBuilder;
import org.opensaml.saml.common.SAMLVersion;
import org.opensaml.saml.ext.reqattr.RequestedAttributes;
+import org.opensaml.saml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration;
import org.opensaml.saml.saml2.core.AuthnRequest;
import org.opensaml.saml.saml2.core.Extensions;
@@ -110,6 +111,9 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
/** Optional strategy to populate request with a {@link NameID}. */
@Nullable private Function<ProfileRequestContext,NameID> nameIDLookupStrategy;
+ /** Convert requested principals of unknown types into SAML AC classes. */
+ private boolean convertUnknownRequestedPrincipals;
+
/** The generator to use. */
@NonnullBeforeExec private IdentifierGenerationStrategy idGenerator;
@@ -142,6 +146,22 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
proxiedRequesterContextLookupStrategy = prcls;
}
+ /**
+ * Sets whether to convert unknown/non-SAML {@link Principal} objects returned for use
+ * in the {@link RequestedAuthnContext} population step into SAML {@link AuthnContextClassRef}
+ * values.
+ *
+ * <p>Defaults to false.</p>
+ *
+ * @param flag flag to set
+ *
+ * @since 5.1.0
+ */
+ public void setConvertUnknownRequestedPrincipals(final boolean flag) {
+ checkSetterPreconditions();
+ convertUnknownRequestedPrincipals = flag;
+ }
+
/**
* Set whether to overwrite an existing message.
*
@@ -353,7 +373,6 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
assert omc != null;
omc.setMessage(object);
}
-// Checkstyle: MethodLength ON
/**
* Build a {@link RequestedAuthnContext} if warranted.
@@ -423,8 +442,33 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
return rac;
}
+ if (convertUnknownRequestedPrincipals) {
+ final SAMLObjectBuilder<AuthnContextClassRef> classBuilder =
+ (SAMLObjectBuilder<AuthnContextClassRef>) bf.<AuthnContextClassRef>ensureBuilder(
+ AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
+ final List<AuthnContextClassRef> unknownPrincipals = principals.stream()
+ .map(p -> {
+ final AuthnContextClassRef ref = classBuilder.buildObject();
+ ref.setURI(p.getName());
+ return ref;
+ })
+ .collect(Collectors.toUnmodifiableList());
+ final RequestedAuthnContext rac = builder.buildObject();
+ rac.getAuthnContextClassRefs().addAll(unknownPrincipals);
+
+ if (log.isDebugEnabled()) {
+ log.debug("{} Setting RequestedAuthnContext class refs to {}", getLogPrefix(),
+ principals.stream()
+ .map(Principal::getName)
+ .collect(Collectors.toUnmodifiableList()));
+ }
+
+ return rac;
+ }
+
return null;
}
+// Checkstyle: MethodLength ON
/**
* Build a {@link Subject} element if necessary.
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfigurationTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfigurationTest.java
index 7a3c797c6..b6d447344 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfigurationTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfigurationTest.java
@@ -25,6 +25,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
import org.testng.Assert;
import org.testng.annotations.Test;
+import java.security.Principal;
import java.time.Duration;
import java.util.*;
@@ -190,7 +191,7 @@ final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
Assert.assertTrue(config.getDefaultAuthenticationMethods(null).isEmpty());
- final List<AuthenticationMethodPrincipal> principals = new ArrayList<>();
+ final List<Principal> principals = new ArrayList<>();
principals.add(new AuthenticationMethodPrincipal("foo"));
principals.add(new AuthenticationMethodPrincipal("bar"));
@@ -202,7 +203,7 @@ final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration
public void testIndirectDefaultAuthenticationMethods() {
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- final List<AuthenticationMethodPrincipal> principals = new ArrayList<>();
+ final List<Principal> principals = new ArrayList<>();
principals.add(new AuthenticationMethodPrincipal("foo"));
principals.add(new AuthenticationMethodPrincipal("bar"));
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfigurationTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfigurationTest.java
index d89ca0f0e..43be8c553 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfigurationTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfigurationTest.java
@@ -14,6 +14,7 @@
package net.shibboleth.idp.saml.saml2.profile.config.impl;
+import java.security.Principal;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -229,7 +230,7 @@ final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
Assert.assertTrue(config.getDefaultAuthenticationMethods(null).isEmpty());
- final List<AuthnContextClassRefPrincipal> principals = new ArrayList<>();
+ final List<Principal> principals = new ArrayList<>();
principals.add(new AuthnContextClassRefPrincipal("foo"));
principals.add(new AuthnContextClassRefPrincipal("bar"));
@@ -241,7 +242,7 @@ final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration
public void testIndirectDefaultAuthenticationMethods() {
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- final List<AuthnContextClassRefPrincipal> principals = new ArrayList<>();
+ final List<Principal> principals = new ArrayList<>();
principals.add(new AuthnContextClassRefPrincipal("foo"));
principals.add(new AuthnContextClassRefPrincipal("bar"));
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/tests/ProxyAwareDefaultAuthenticationMethodsLookupFunctionTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/tests/ProxyAwareDefaultAuthenticationMethodsLookupFunctionTest.java
index 3be550058..fde4ba2de 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/tests/ProxyAwareDefaultAuthenticationMethodsLookupFunctionTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/tests/ProxyAwareDefaultAuthenticationMethodsLookupFunctionTest.java
@@ -17,7 +17,6 @@ package net.shibboleth.idp.saml.saml2.profile.config.navigate.tests;
import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -57,7 +56,7 @@ public class ProxyAwareDefaultAuthenticationMethodsLookupFunctionTest extends Op
@Test
public void testEmptyTree() {
- final Collection<AuthnContextClassRefPrincipal> principals = fn.apply(prc1);
+ final Collection<Principal> principals = fn.apply(prc1);
Assert.assertTrue(principals.isEmpty());
}
@@ -67,7 +66,7 @@ public class ProxyAwareDefaultAuthenticationMethodsLookupFunctionTest extends Op
new AuthnContextClassRefPrincipal("foo"),
new AuthnContextClassRefPrincipal("bar")));
- final Collection<AuthnContextClassRefPrincipal> principals = fn.apply(prc1);
+ final Collection<Principal> principals = fn.apply(prc1);
Assert.assertTrue(principals.isEmpty());
}
@@ -75,9 +74,10 @@ public class ProxyAwareDefaultAuthenticationMethodsLookupFunctionTest extends Op
public void testPassthrough() {
rpc.setRequestedPrincipals(CollectionSupport.listOf(
new AuthnContextClassRefPrincipal("foo"),
- new AuthnContextClassRefPrincipal("bar")));
+ new AuthnContextClassRefPrincipal("bar"),
+ new AuthenticationMethodPrincipal("baz")));
- final Collection<AuthnContextClassRefPrincipal> principals = fn.apply(prc2);
+ final Collection<Principal> principals = fn.apply(prc2);
Assert.assertEquals(principals, rpc.getRequestedPrincipals());
}
@@ -91,15 +91,15 @@ public class ProxyAwareDefaultAuthenticationMethodsLookupFunctionTest extends Op
final Map<Principal,Collection<Principal>> mappings = new HashMap<>();
mappings.put(new AuthnContextClassRefPrincipal("foo"), CollectionSupport.emptyList());
mappings.put(new AuthenticationMethodPrincipal("baz"),
- List.of(new AuthnContextClassRefPrincipal("frobnitz"),
+ CollectionSupport.listOf(new AuthnContextClassRefPrincipal("frobnitz"),
new AuthnContextDeclRefPrincipal("grue"),
new AuthnContextClassRefPrincipal("zorkmid")));
fn.setMappings(mappings);
- final Collection<AuthnContextClassRefPrincipal> principals = fn.apply(prc2);
+ final Collection<Principal> principals = fn.apply(prc2);
Assert.assertEquals(principals.stream().map(p -> p.getName()).collect(Collectors.toUnmodifiableList()),
- List.of("bar", "frobnitz", "zorkmid"));
+ CollectionSupport.listOf("bar", "frobnitz", "grue", "zorkmid"));
}
}
\ No newline at end of file
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequestTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequestTest.java
index c78e9d3da..ea45617a9 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequestTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequestTest.java
@@ -20,7 +20,6 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
-import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
@@ -58,12 +57,14 @@ import org.testng.annotations.Test;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.authn.context.RequestedPrincipalContext;
+import net.shibboleth.idp.authn.testing.TestPrincipal;
import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
import net.shibboleth.idp.profile.testing.ActionTestingSupport;
import net.shibboleth.idp.profile.testing.RequestContextBuilder;
import net.shibboleth.idp.saml.authn.principal.AuthenticationMethodPrincipal;
import net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal;
+import net.shibboleth.idp.saml.authn.principal.AuthnContextDeclRefPrincipal;
import net.shibboleth.idp.saml.saml2.profile.config.impl.BrowserSSOProfileConfiguration;
import net.shibboleth.profile.context.RelyingPartyContext;
import net.shibboleth.profile.context.navigate.IssuerLookupFunction;
@@ -117,6 +118,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
action.setAuthenticationContextLookupStrategy(new ParentContextLookup<>(AuthenticationContext.class));
action.setIssuerLookupStrategy(new IssuerLookupFunction());
action.setNameIDLookupStrategy(prc -> nameID);
+ action.setConvertUnknownRequestedPrincipals(true);
action.initialize();
}
@@ -446,7 +448,7 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
final RequestedPrincipalContext reqctx = ac.ensureSubcontext(RequestedPrincipalContext.class);
reqctx.setOperator("exact");
reqctx.setRequestedPrincipals(
- Arrays.asList(new AuthnContextClassRefPrincipal(AuthnContext.KERBEROS_AUTHN_CTX),
+ CollectionSupport.listOf(new AuthnContextClassRefPrincipal(AuthnContext.KERBEROS_AUTHN_CTX),
new AuthenticationMethodPrincipal(AuthenticationStatement.KERBEROS_AUTHN_METHOD),
new AuthnContextClassRefPrincipal(AuthnContext.X509_AUTHN_CTX)));
@@ -466,11 +468,12 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
assertEquals(rac.getAuthnContextClassRefs().size(), 2);
assertEquals(rac.getAuthnContextClassRefs().get(0).getURI(), AuthnContext.KERBEROS_AUTHN_CTX);
assertEquals(rac.getAuthnContextClassRefs().get(1).getURI(), AuthnContext.X509_AUTHN_CTX);
+
final BrowserSSOProfileConfiguration bspc = (BrowserSSOProfileConfiguration) rpc.getProfileConfig();
assert bspc!=null;
bspc.setAuthnContextComparison(AuthnContextComparisonTypeEnumeration.EXACT);
bspc.setDefaultAuthenticationMethods(
- Arrays.asList(new AuthnContextClassRefPrincipal(AuthnContext.KERBEROS_AUTHN_CTX),
+ CollectionSupport.listOf(new AuthnContextClassRefPrincipal(AuthnContext.KERBEROS_AUTHN_CTX),
new AuthnContextClassRefPrincipal(AuthnContext.X509_AUTHN_CTX)));
omc.setMessage(null);
@@ -487,4 +490,58 @@ public class AddAuthnRequestTest extends OpenSAMLInitBaseTestCase {
assertEquals(rac.getAuthnContextClassRefs().get(1).getURI(), AuthnContext.X509_AUTHN_CTX);
}
+ /** Test that the action maps DeclRefs into RequestedAuthnContext. */
+ @SuppressWarnings("null")
+ @Test public void testDeclRefs() {
+ final RequestedPrincipalContext reqctx = ac.ensureSubcontext(RequestedPrincipalContext.class);
+ reqctx.setOperator("exact");
+ reqctx.setRequestedPrincipals(
+ CollectionSupport.listOf(new AuthnContextDeclRefPrincipal("https://example.org/ac1"),
+ new AuthnContextDeclRefPrincipal("https://example.org/ac2")));
+
+ final Event event = action.execute(rc);
+ ActionTestingSupport.assertProceedEvent(event);
+
+ final MessageContext omc = prc2.getOutboundMessageContext();
+ assert omc!=null;
+ assertNotNull(omc.getMessage());
+ assertTrue(omc.getMessage() instanceof AuthnRequest);
+
+ final AuthnRequest request = (AuthnRequest) omc.getMessage();
+ assert request!=null;
+ final RequestedAuthnContext rac = request.getRequestedAuthnContext();
+ assert rac!=null;
+ assertEquals(rac.getComparison(), AuthnContextComparisonTypeEnumeration.EXACT);
+ assertEquals(rac.getAuthnContextDeclRefs().size(), 2);
+ assertEquals(rac.getAuthnContextDeclRefs().get(0).getURI(), "https://example.org/ac1");
+ assertEquals(rac.getAuthnContextDeclRefs().get(1).getURI(), "https://example.org/ac2");
+ }
+
+ /** Test that the action maps unrecognized Principals into RequestedAuthnContext. */
+ @SuppressWarnings("null")
+ @Test public void testUnknownPrincipals() {
+ final RequestedPrincipalContext reqctx = ac.ensureSubcontext(RequestedPrincipalContext.class);
+ reqctx.setOperator("exact");
+ reqctx.setRequestedPrincipals(
+ CollectionSupport.listOf(new TestPrincipal("https://example.org/ac1"),
+ new AuthenticationMethodPrincipal("https://example.org/ac2")));
+
+ final Event event = action.execute(rc);
+ ActionTestingSupport.assertProceedEvent(event);
+
+ final MessageContext omc = prc2.getOutboundMessageContext();
+ assert omc!=null;
+ assertNotNull(omc.getMessage());
+ assertTrue(omc.getMessage() instanceof AuthnRequest);
+
+ final AuthnRequest request = (AuthnRequest) omc.getMessage();
+ assert request!=null;
+ final RequestedAuthnContext rac = request.getRequestedAuthnContext();
+ assert rac!=null;
+ assertEquals(rac.getComparison(), AuthnContextComparisonTypeEnumeration.EXACT);
+ assertEquals(rac.getAuthnContextClassRefs().size(), 2);
+ assertEquals(rac.getAuthnContextClassRefs().get(0).getURI(), "https://example.org/ac1");
+ assertEquals(rac.getAuthnContextClassRefs().get(1).getURI(), "https://example.org/ac2");
+ }
+
}
\ 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