[java-plugin-shibd-oidc] branch main updated: Improve authentication request lookup strategies
Phil Smart
philip.smart at jisc.ac.uk
Fri Oct 3 12:54:18 UTC 2025
This is an automated email from the git hooks/post-receive script.
philsmart pushed a commit to branch main
in repository java-plugin-shibd-oidc.
View the commit online:
http://git.shibboleth.net/view/?p=java-plugin-shibd-oidc.git;a=commit;h=eeb6bef1a058b1a25aa4872b2c7588785bb22575
The following commit(s) were added to refs/heads/main by this push:
new eeb6bef Improve authentication request lookup strategies
eeb6bef is described below
commit eeb6bef1a058b1a25aa4872b2c7588785bb22575
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Oct 3 13:54:15 2025 +0100
Improve authentication request lookup strategies
- Add disallowed feature support
- Add fallback to profile config (for those driven by the DDF)
- Improve tests
---
pom.xml | 2 +-
.../idp/flows/sp/initiator/oidc/oidc-beans.xml | 13 +-
.../sp/oidc/flows/OIDCAuthenticationFlowTest.java | 105 ++++++++------
.../idp/module/conf/sp/oidc-test.properties | 2 +-
...tAgentAndRelyingPartyContextLookupFunction.java | 24 +++-
...uthenticationContextClassRefLookupStrategy.java | 32 +++--
.../impl/DefaultRedirectUriCreationFunction.java | 151 ---------------------
.../impl/DisplayParameterLookupStrategy.java | 18 ++-
.../impl/ForceAuthnParameterLookupStrategy.java | 51 ++++---
.../oidc/profile/impl/LoginHintLookupStrategy.java | 37 ++++-
.../sp/oidc/profile/impl/MaxAgeLookupStrategy.java | 18 ++-
.../profile/impl/ResponseModeLookupStrategy.java | 5 +-
.../profile/impl/ResponseTypeLookupStrategy.java | 8 +-
.../impl/SetAuthenticationRequestTimeHandler.java | 3 +-
.../AbstractAuthenticationLookupStrategyTest.java | 84 ++++++++++++
.../impl/DisplayParameterLookupStrategyTest.java | 84 ++++++++++++
.../ForceAuthnParameterLookupStrategyTest.java | 106 +++++++++++++++
17 files changed, 479 insertions(+), 264 deletions(-)
diff --git a/pom.xml b/pom.xml
index d81cbb3..f44c83f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@ copyright/license information. -->
<shib-profile.groupId>net.shibboleth</shib-profile.groupId>
<shib-profile.version>5.2.0-SNAPSHOT</shib-profile.version>
<oidc-common.groupId>net.shibboleth.oidc</oidc-common.groupId>
- <oidc-common.version>3.3.0</oidc-common.version>
+ <oidc-common.version>3.3.1-SNAPSHOT</oidc-common.version>
<oidc-config.groupId>net.shibboleth.idp.plugin.config.oidc</oidc-config.groupId>
<oidc-config.version>3.0.0</oidc-config.version>
<idp.groupId>net.shibboleth.idp</idp.groupId>
diff --git a/sp-oidc-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/oidc/oidc-beans.xml b/sp-oidc-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/oidc/oidc-beans.xml
index e1d1855..4646a30 100644
--- a/sp-oidc-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/oidc/oidc-beans.xml
+++ b/sp-oidc-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/oidc/oidc-beans.xml
@@ -182,17 +182,10 @@
<property name="errorEvent">
<util:constant static-field="org.opensaml.profile.action.EventIds.INVALID_MESSAGE" />
</property>
- </bean>
-
- <!-- TODO, this needs to come from the agent config? -->
- <bean id="DefaultRedirectUriCreationStrategy" scope="prototype"
- p:callbackServletPath="sp/callback"
- p:allowedOrigins="%{sp.oidc.redirecturl.allowedOrigins:}"
- class="net.shibboleth.sp.oidc.profile.impl.DefaultRedirectUriCreationFunction" />
+ </bean>
<bean id="RequestObjectRequiredAndSupportedPredicate" scope="prototype"
- class="net.shibboleth.sp.oidc.config.logic.RequestObjectRequiredAndSupported" />
-
+ class="net.shibboleth.sp.oidc.config.logic.RequestObjectRequiredAndSupported" />
<bean id="PopulateRequestObjectSignatureSigningParameters" scope="prototype"
class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureSigningParameters"
@@ -321,7 +314,7 @@
</property>
</bean>
<bean id="SetAuthenticationRequestTime"
- class="net.shibboleth.sp.oidc.profile.impl.SetAuthenticationRequestTimeHandler" scope="prototype"/>
+ class="net.shibboleth.sp.oidc.profile.request.impl.SetAuthenticationRequestTimeHandler" scope="prototype"/>
</list>
</property>
</bean>
diff --git a/sp-oidc-conf-impl/src/test/java/net/shibboleth/sp/oidc/flows/OIDCAuthenticationFlowTest.java b/sp-oidc-conf-impl/src/test/java/net/shibboleth/sp/oidc/flows/OIDCAuthenticationFlowTest.java
index 59bdc14..a4b2d97 100644
--- a/sp-oidc-conf-impl/src/test/java/net/shibboleth/sp/oidc/flows/OIDCAuthenticationFlowTest.java
+++ b/sp-oidc-conf-impl/src/test/java/net/shibboleth/sp/oidc/flows/OIDCAuthenticationFlowTest.java
@@ -27,11 +27,14 @@ import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.common.binding.SAMLBindingSupport;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.util.ObjectUtils;
import org.springframework.webflow.executor.FlowExecutionResult;
import org.testng.Assert;
import org.testng.annotations.Test;
-import com.nimbusds.oauth2.sdk.AuthorizationRequest;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.PlainJWT;
+import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.openid.connect.sdk.AuthenticationRequest;
@@ -46,7 +49,7 @@ import net.shibboleth.sp.profile.SPConstants;
import net.shibboleth.sp.profile.impl.IssueCorrelationCookie;
/**
- *
+ * TODO these tests work using a signed request object atm, but the asserts need to work on url params as well
*/
@ContextConfiguration(
locations = {
@@ -74,7 +77,7 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
}
/**
- * Basic flow test, mainly for TDD.
+ * Basic flow test.
*
* @throws IOException on error
* @throws MessageDecodingException
@@ -93,17 +96,16 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
- final AuthorizationRequest req = validateOutputMessage(result);
+ validateOutputMessage(result);
}
/**
* Basic flow test with forceAuthn.
*
- * @throws IOException on error
- * @throws MessageDecodingException
+ * @throws Exception on error
*/
@Test
- public void testForceAuthnFromAgent() throws IOException, MessageDecodingException {
+ public void testForceAuthnFromAgent() throws Exception {
setDefaultAuth();
final DDF input = new DDF(null).structure();
@@ -117,17 +119,18 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
- final AuthorizationRequest req = validateOutputMessage(result);
+ final AuthenticationRequest req = validateOutputMessage(result);
+ assertValueForParameter(req, "max_age", 0l);
+ assertValueForParameter(req, "prompt", "login");
}
/**
* Basic flow test with max_age.
*
- * @throws IOException on error
- * @throws MessageDecodingException
+ * @throws Exception on error
*/
@Test
- public void testMaxAgeFromAgent() throws IOException, MessageDecodingException {
+ public void testMaxAgeFromAgent() throws Exception {
setDefaultAuth();
final DDF input = new DDF(null).structure();
@@ -141,17 +144,17 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
- final AuthorizationRequest req = validateOutputMessage(result);
+ final AuthenticationRequest req = validateOutputMessage(result);
+ assertValueForParameter(req, "max_age", 60l);
}
/**
* Basic flow test with prompt=none.
*
- * @throws IOException on error
- * @throws MessageDecodingException
+ * @throws Exception on error
*/
@Test
- public void testPromptFromAgent() throws IOException, MessageDecodingException {
+ public void testPromptFromAgent() throws Exception {
setDefaultAuth();
final DDF input = new DDF(null).structure();
@@ -165,17 +168,17 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
- final AuthorizationRequest req = validateOutputMessage(result);
+ final AuthenticationRequest req = validateOutputMessage(result);
+ assertValueForParameter(req, "prompt", "none");
}
/**
- * Basic flow test with prompt=none.
+ * Basic flow test with two ACRs.
*
- * @throws IOException on error
- * @throws MessageDecodingException
+ * @throws Exception on error
*/
@Test
- public void testACRFromAgent() throws IOException, MessageDecodingException {
+ public void testACRFromAgent() throws Exception {
setDefaultAuth();
final DDF input = new DDF(null).structure();
@@ -192,17 +195,17 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
- final AuthorizationRequest req = validateOutputMessage(result);
+ final AuthenticationRequest req = validateOutputMessage(result);
+ assertValueForParameter(req, "acr_values", "loa1 loa2");
}
/**
* Basic flow test with scope=email profile.
*
- * @throws IOException on error
- * @throws MessageDecodingException
+ * @throws Exception on error
*/
@Test
- public void testScopeFromAgent() throws IOException, MessageDecodingException {
+ public void testScopeFromAgent() throws Exception {
setDefaultAuth();
final DDF input = new DDF(null).structure();
@@ -215,19 +218,19 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
- //TODO TEST THE SCOPES
- final AuthorizationRequest req = validateOutputMessage(result);
+
+ final AuthenticationRequest req = validateOutputMessage(result);
+ assertValueForParameter(req, "scope", "openid email profile");
}
/**
* Basic flow test with display.
*
- * @throws IOException on error
- * @throws MessageDecodingException
+ * @throws Exception on error
*/
@Test
- public void testDisplayFromAgent() throws IOException, MessageDecodingException {
+ public void testDisplayFromAgent() throws Exception {
setDefaultAuth();
final DDF input = new DDF(null).structure();
@@ -240,8 +243,9 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
-
- final AuthorizationRequest req = validateOutputMessage(result);
+
+ final AuthenticationRequest req = validateOutputMessage(result);
+ assertValueForParameter(req, "display", "page");
}
/**
@@ -253,7 +257,7 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
*
* @throws MessageDecodingException
*/
- @Nonnull private AuthorizationRequest validateOutputMessage(@Nonnull final FlowExecutionResult result)
+ @Nonnull private AuthenticationRequest validateOutputMessage(@Nonnull final FlowExecutionResult result)
throws MessageDecodingException {
final ProfileRequestContext prc = retrieveProfileRequestContext(result);
assert prc != null;
@@ -266,7 +270,7 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
final DDF http = output.getmember(RemotedHttpServletResponse.STRUCTURE_NAME);
Assert.assertTrue(http.isstruct());
- final AuthorizationRequest authnRequest;
+ final AuthenticationRequest authnRequest;
final byte[] redirect = http.getmember(RemotedHttpServletResponse.REDIRECT).unsafe_string();
if (redirect != null) {
final String redirectURL = new String(redirect, StandardCharsets.UTF_8);
@@ -310,14 +314,37 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
//TODO Not Set yet: Assert.assertTrue(foundCorrelationCookie);
}
-// final NameIDPolicy pol = authnRequest.getNameIDPolicy();
-// assert pol != null;
-// assertTrue(pol.getAllowCreate());
-// Assert.assertEquals(pol.getFormat(), format);
return authnRequest;
}
+ /**
+ * Find the String value for the parameter from the {@link AuthenticationRequest}, either in the params or inside
+ * a claim in the Request Object.
+ *
+ * @param request the request to locate the parameter from
+ * @param claim the claim to find
+ *
+ * @return the value if found.
+ * @throws java.text.ParseException
+ */
+ private void assertValueForParameter(final AuthenticationRequest request, @Nonnull final String claim,
+ final Object expectedClaimValue)
+ throws java.text.ParseException {
+ JWTClaimsSet requestObjectClaims = null;
+ if (request.getRequestObject() instanceof final SignedJWT signed) {
+ requestObjectClaims = signed.getJWTClaimsSet();
+ } else if (request.getRequestObject() instanceof final PlainJWT jwt){
+ requestObjectClaims = jwt.getJWTClaimsSet();
+ }
+
+ Object claimValue = null;
+ if (requestObjectClaims != null) {
+ claimValue = requestObjectClaims.getClaim(claim);
+ }
+ assertTrue(ObjectUtils.nullSafeEquals(claimValue, expectedClaimValue));
+ }
+
/**
* Decodes an OAuth authorization message encoded via HTTP-Redirect binding.
*
@@ -327,13 +354,13 @@ public class OIDCAuthenticationFlowTest extends AbstractSPFlowTest {
* @return decoded message
* @throws MessageDecodingException
*/
- @Nonnull protected AuthorizationRequest decodeRedirect(@Nullable final String url, @Nullable final String relayState)
+ @Nonnull protected AuthenticationRequest decodeRedirect(@Nullable final String url, @Nullable final String relayState)
throws MessageDecodingException {
if (url == null) {
throw new MessageDecodingException("URl is null");
}
try {
- return AuthorizationRequest.parse(new URI(url));
+ return AuthenticationRequest.parse(new URI(url));
} catch (final ParseException | URISyntaxException e) {
throw new MessageDecodingException("No message, or incorrect type.", e);
}
diff --git a/sp-oidc-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/sp/oidc-test.properties b/sp-oidc-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/sp/oidc-test.properties
index bff09e5..f374c9b 100644
--- a/sp-oidc-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/sp/oidc-test.properties
+++ b/sp-oidc-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/sp/oidc-test.properties
@@ -20,7 +20,7 @@ sp.oidc.signing.rsa.enc.key = %{idp.home}/credentials/sp/sp-encryption-rsa.jwk
sp.oidc.redirecturl.allowedOrigins = http://localhost
## TEST ENC FOR NOW from profile config
-idp.oidc.requestobject.encrypted = true
+idp.oidc.requestobject.encrypted = false
#idp.oidc.encryption.config = dummy.oidc.EncryptionConfiguration
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/AbstractAgentAndRelyingPartyContextLookupFunction.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/AbstractAgentAndRelyingPartyContextLookupFunction.java
index 69d1f4d..48177ab 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/AbstractAgentAndRelyingPartyContextLookupFunction.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/AbstractAgentAndRelyingPartyContextLookupFunction.java
@@ -96,7 +96,7 @@ public abstract class AbstractAgentAndRelyingPartyContextLookupFunction<ResultTy
*
* @return the agent
*/
- @Nullable public Agent getAgent(@Nullable final MessageContext input) {
+ @Nullable protected Agent getAgent(@Nullable final MessageContext input) {
final AgentRequestContext arc = agentRequestContextLookupStrategy.apply(input);
if (arc == null) {
return null;
@@ -109,7 +109,7 @@ public abstract class AbstractAgentAndRelyingPartyContextLookupFunction<ResultTy
*
* @return the agent
*/
- @Nullable public Application getApplication(@Nullable final MessageContext input) {
+ @Nullable protected Application getApplication(@Nullable final MessageContext input) {
final AgentRequestContext arc = agentRequestContextLookupStrategy.apply(input);
if (arc == null) {
return null;
@@ -122,7 +122,7 @@ public abstract class AbstractAgentAndRelyingPartyContextLookupFunction<ResultTy
*
* @return the input or output DDF
*/
- @Nullable public DDF getDDF(@Nullable final MessageContext input, @Nonnull final DDFDirection direction) {
+ @Nullable protected DDF getDDF(@Nullable final MessageContext input, @Nonnull final DDFDirection direction) {
final AgentRequestContext arc = agentRequestContextLookupStrategy.apply(input);
if (arc == null) {
return null;
@@ -136,6 +136,24 @@ public abstract class AbstractAgentAndRelyingPartyContextLookupFunction<ResultTy
return null;
}
}
+ /**
+ * Determine if the feature is disallowed for the current relying party configuration.
+ *
+ * @param feature the feature to check
+ * @param messageCtx the message context to extract the profile configuration from
+ *
+ * @return true iff the feature is disallowed, false otherwise
+ */
+ protected boolean isFeatureDisallowed(final int feature, @Nullable final MessageContext messageCtx) {
+
+ final OIDCAuthenticationRelyingPartyProfileConfiguration config =
+ getOIDCRelyingPartyProfileConfiguration(messageCtx);
+
+ if (config != null) {
+ return config.isFeatureDisallowed(PRC_LOOKUP.apply(messageCtx), feature);
+ }
+ return false;
+ }
/**
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/AuthenticationContextClassRefLookupStrategy.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/AuthenticationContextClassRefLookupStrategy.java
index 935b2e7..e569b4e 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/AuthenticationContextClassRefLookupStrategy.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/AuthenticationContextClassRefLookupStrategy.java
@@ -25,6 +25,8 @@ import org.slf4j.Logger;
import com.nimbusds.openid.connect.sdk.claims.ACR;
+import net.shibboleth.oidc.profile.config.OIDCAuthenticationRelyingPartyProfileConfiguration;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.sp.ddf.DDF;
@@ -32,12 +34,10 @@ import net.shibboleth.sp.oidc.profile.OIDCInitiatorConstants;
/**
- * A lookup strategy that extracts a list of {@link ACR} (Authentication Context Class References)
- * from the input {@link DDF} message within the current {@link MessageContext}.
- * <p>
- * The extracted strings are converted into {@link ACR} objects and returned as an immutable list.
- * If no input is available or the context is missing, the strategy returns {@code null}.
- * </p>
+ * A strategy function that extracts requested Authentication Context Class References (ACRs)
+ * from the inbound {@link MessageContext} and returns them as a list of {@link ACR} objects. Takes them from
+ * the inbound {@link DDF} object if they exist, if they do not exist or they were disallowed by the Hub configuration
+ * they are taken from the relying party configuration.
*/
public class AuthenticationContextClassRefLookupStrategy
extends AbstractAgentAndRelyingPartyContextLookupFunction<List<ACR>> {
@@ -50,18 +50,24 @@ public class AuthenticationContextClassRefLookupStrategy
final DDF input = getDDF(messageCtx, DDFDirection.INPUT);
if (input == null) {
return null;
- }
- final List<String> classrefs = input.getmember(OIDCInitiatorConstants.AUTHN_CONTEXT_CLASS_REF).asList()
+ }
+ final OIDCAuthenticationRelyingPartyProfileConfiguration rpConfig =
+ getOIDCRelyingPartyProfileConfiguration(messageCtx);
+
+ List<String> classrefs = input.getmember(OIDCInitiatorConstants.AUTHN_CONTEXT_CLASS_REF).asList()
.stream()
.map(DDF::string)
.collect(CollectionSupport.nonnullCollector(Collectors.toUnmodifiableList())).get();
+ if (!classrefs.isEmpty() && isFeatureDisallowed(OIDCAuthorizationConfiguration.FEATURE_ESSENTIAL_ACR_REQUEST,
+ messageCtx)) {
+ log.warn("Agent disallowed from overriding ACR request");
+ classrefs = CollectionSupport.emptyList();
+ }
-// if (!classrefs.isEmpty() && profileConfiguration.isFeatureDisallowed(profileRequestContext,
-// BrowserSSOProfileConfiguration.FEATURE_AUTHNCONTEXT)) {
-// log.warn("{} Agent disallowed from overriding RequestedAuthnContext", getLogPrefix());
-// classrefs = CollectionSupport.emptyList();
-// }
+ if (rpConfig != null && classrefs.isEmpty()) {
+ rpConfig.getAuthnContextClassRefs(PRC_LOOKUP.apply(messageCtx));
+ }
return classrefs.stream().map(ACR::new).toList();
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/DefaultRedirectUriCreationFunction.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/DefaultRedirectUriCreationFunction.java
deleted file mode 100644
index d3c85ed..0000000
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/DefaultRedirectUriCreationFunction.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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.oidc.profile.impl;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.Set;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import jakarta.servlet.http.HttpServletRequest;
-import net.shibboleth.oidc.profile.messaging.context.OIDCPeerEntityContext;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
-import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.primitive.StringSupport;
-import net.shibboleth.sp.oidc.context.OAuth2ClientContext;
-
-/**
- * Constructive, pure, function that returns a redirect_uri from one of (ordered):
- * <ol>
- * <li>A pre-registered redirect_uri on the {@link OAuth2ClientContext#getRedirectUriOverride()}.
- * Or, if none are pre-registered;
- * <li>Derived from the HTTP Servlet request server parameters, checking the origin
- * against an allowed set of origins - to prevent Host header injection.
- * </ol>
- *
- * <p>Returns null if one can not be constructed.</p>
- *
- * <p>Is thread-safe and immutable</p>
- */
- at ThreadSafeAfterInit
-public class DefaultRedirectUriCreationFunction extends AbstractIdentifiableInitializableComponent
- implements BiFunction<HttpServletRequest, ProfileRequestContext, URI> {
-
- /** Class logger. */
- @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultRedirectUriCreationFunction.class);
-
- /** The strategy used to lookup or create the {@link OAuth2ClientContext} for storing the client_id.*/
- @Nonnull private Function<ProfileRequestContext, OAuth2ClientContext> oauth2ClientContextLookupStrategy;
-
- /** The path, excluding the context and servlet paths, to the RP callback handler.*/
- @NonnullAfterInit @NotEmpty private String callbackServletPath;
-
- /**
- * A set of 'allowed' origins that can be used as the scheme, host, and port portion of the redirectURI.
- * Can be null, if so a redirect_uri must be specified in the context tree.
- */
- @NonnullAfterInit private Set<String> allowedOrigins;
-
- /**
- * Constructor.
- */
- public DefaultRedirectUriCreationFunction() {
- // Default under OIDCPeerEntityContext in the outbound context (create true) under the nested PRC.
- oauth2ClientContextLookupStrategy = new ChildContextLookup<>(OAuth2ClientContext.class).compose(
- new ChildContextLookup<>(OIDCPeerEntityContext.class).compose(
- new OutboundMessageContextLookup()));
- }
-
- @Override
- protected void doInitialize() throws ComponentInitializationException {
- super.doInitialize();
-
- if (StringSupport.trimOrNull(callbackServletPath) == null) {
- throw new ComponentInitializationException("Callback servlet path can not be null");
- }
- if (allowedOrigins == null) {
- allowedOrigins = Collections.emptySet();
- }
- }
-
- /**
- * Set the path segment relative to the servlet path of the callback endpoint.
- *
- * @param path the callback servlet path
- */
- public void setCallbackServletPath(@Nonnull @NotEmpty final String path) {
- checkSetterPreconditions();
-
- callbackServletPath = Constraint.isNotEmpty(path, "callbackServletPath can not be null");
- }
-
- /**
- * Set the allowed origins to use if a redirect_uri is computed.
- *
- * @param origins the origins
- */
- public void setAllowedOrigins(@Nullable final Set<String> origins) {
- checkSetterPreconditions();
-
- if (origins == null) {
- allowedOrigins = Collections.emptySet();
- }
- allowedOrigins = Collections.unmodifiableSet(origins);
- }
-
-
- /**
- * Set the strategy to lookup the {@link OAuth2ClientContext}
- * from the {@link ProfileRequestContext}.
- *
- * @param strgy the strategy.
- */
- public void setOAuth2ClientContextLookupStrategy(
- @Nonnull final Function<ProfileRequestContext, OAuth2ClientContext> strgy) {
- checkSetterPreconditions();
-
- oauth2ClientContextLookupStrategy = Constraint.isNotNull(strgy,
- "OAuth2 client context lookup strategy cannot be null");
- }
-
- @Override
- @Nullable public URI apply(@Nullable final HttpServletRequest request, @Nullable final ProfileRequestContext prc) {
-
- //TODO from the agent context, but maybe still use allowedOrigins concept? not sure relevant if not comming from
- //user input, depends where the Agent gets it from.
- try {
- return new URI(String.format("%s://%s/%s", "http","localhost","callback"));
- } catch (final URISyntaxException e) {
- return null;
- }
- }
-
-
-}
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/DisplayParameterLookupStrategy.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/DisplayParameterLookupStrategy.java
index 55c0e0d..dd54868 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/DisplayParameterLookupStrategy.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/DisplayParameterLookupStrategy.java
@@ -18,21 +18,29 @@ import javax.annotation.Nullable;
import org.opensaml.messaging.context.MessageContext;
+import net.shibboleth.oidc.profile.config.OIDCAuthenticationRelyingPartyProfileConfiguration;
import net.shibboleth.sp.ddf.DDF;
import net.shibboleth.sp.oidc.profile.OIDCInitiatorConstants;
/**
- * Retrieve the 'display' parameter from the {@link DDF}.
+ * Retrieve the 'display' parameter from either the {@link DDF} if present, or the profile configuration.
*/
public class DisplayParameterLookupStrategy extends AbstractAgentAndRelyingPartyContextLookupFunction<String> {
/** {@inheritDoc} */
@Nullable public String apply(final MessageContext messageCtx) {
+
final DDF input = getDDF(messageCtx, DDFDirection.INPUT);
- if (input == null) {
- return null;
+ if (input != null) {
+ final String display = input.getmember(OIDCInitiatorConstants.DISPLAY).string();
+ if (display != null) {
+ return display;
+ }
}
- return input.getmember(OIDCInitiatorConstants.DISPLAY).string();
+
+ final OIDCAuthenticationRelyingPartyProfileConfiguration rpConfig =
+ getOIDCRelyingPartyProfileConfiguration(messageCtx);
+
+ return rpConfig != null ? rpConfig.getDisplay(PRC_LOOKUP.apply(messageCtx)) : null;
}
-
}
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ForceAuthnParameterLookupStrategy.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ForceAuthnParameterLookupStrategy.java
index 0f93fb7..1ec550c 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ForceAuthnParameterLookupStrategy.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ForceAuthnParameterLookupStrategy.java
@@ -14,17 +14,33 @@
package net.shibboleth.sp.oidc.profile.impl;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opensaml.messaging.context.MessageContext;
+import org.slf4j.Logger;
+import net.shibboleth.oidc.profile.config.OIDCAuthenticationRelyingPartyProfileConfiguration;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.sp.ddf.DDF;
import net.shibboleth.sp.oidc.profile.OIDCInitiatorConstants;
/**
- * Retrieve the ForceAuthn parameter from the {@link DDF}.
+ * Retrieve the ForceAuthn parameter.
+ *
+ * <p>This method first checks the inbound {@link DDF} input for the {@code FORCE_AUTHN} parameter.
+ * If present, set to {@code 1}, and the Hub has not disallowed it, it returns {@code true}. If the feature is
+ * disallowed, it returns {@code false}.</p>
+ *
+ * <p>If the parameter is not present in the {@link DDF}, the method falls back to using the the relying party profile
+ * configuration.</p>
+
*/
public class ForceAuthnParameterLookupStrategy extends AbstractAgentAndRelyingPartyContextLookupFunction<Boolean> {
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ForceAuthnParameterLookupStrategy.class);
/** {@inheritDoc} */
@Nullable public Boolean apply(final MessageContext messageCtx) {
@@ -35,31 +51,22 @@ public class ForceAuthnParameterLookupStrategy extends AbstractAgentAndRelyingPa
final Integer forceAuthn = input.getmember(OIDCInitiatorConstants.FORCE_AUTHN).integer();
if (forceAuthn != null) {
- // TODO disallow feature if set but not allowed
-// if (profileConfiguration.isFeatureDisallowed(profileRequestContext,
-// BrowserSSOProfileConfiguration.FEATURE_FORCEAUTHN)) {
-// log.warn("{} Agent disallowed from overriding ForceAuthn", getLogPrefix());
-// }
- if (forceAuthn == 1) {
+ if (isFeatureDisallowed(OIDCAuthorizationConfiguration.FEATURE_FORCEAUTHN, messageCtx)) {
+ log.warn("Agent disallowed from overriding ForceAuthn");
+ return false;
+ }
+ else if (forceAuthn == 1) {
return true;
}
- return false;
+ }
+
+ final OIDCAuthenticationRelyingPartyProfileConfiguration rpConfig =
+ getOIDCRelyingPartyProfileConfiguration(messageCtx);
+
+ if (rpConfig != null) {
+ return rpConfig.isForceAuthn(PRC_LOOKUP.apply(messageCtx));
}
return false;
- // Else try from Profile config
-// if (getProfileConfiguration().isForceAuthn(lookupProfileRequestContext(messageContext))) {
-// log.trace("{} Setting prompt=login and max_age=0 (ForceAuthn) for OIDC AuthnRequest", getLogPrefix());
-// try {
-// getAuthenticationRequest().setPrompt(Prompt.parse(Prompt.Type.LOGIN.toString()));
-// getAuthenticationRequest().setMaxAge(Duration.ofSeconds(0));
-// } catch (final ParseException e) {
-// // This should never happen
-// throw new MessageHandlerException("Unable to honour force-authn, "
-// + "setting prompt to force-login as failed", e);
-// }
-// } else {
-// log.trace("{} No ForceAuthn requirement, so no prompt or max_age set", getLogPrefix());
-// }
}
}
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/LoginHintLookupStrategy.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/LoginHintLookupStrategy.java
index 8f45297..3d23a25 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/LoginHintLookupStrategy.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/LoginHintLookupStrategy.java
@@ -14,25 +14,56 @@
package net.shibboleth.sp.oidc.profile.impl;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opensaml.messaging.context.MessageContext;
+import org.slf4j.Logger;
+import net.shibboleth.oidc.profile.config.OIDCAuthenticationRelyingPartyProfileConfiguration;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.sp.ddf.DDF;
import net.shibboleth.sp.oidc.profile.OIDCInitiatorConstants;
/**
- * Retrieve the 'login_hint' parameter from the {@link DDF}.
+ * Retrieve the 'login_hint' parameter from the {@link DDF} if it is present and
+ * the Hub configuration has not disallowed the Agent from setting it.
+ *
+ * <p>
+ * If the parameter is not present in the {@link DDF}, the method falls back to
+ * using the the relying party profile configuration.
+ * </p>
*/
public class LoginHintLookupStrategy extends AbstractAgentAndRelyingPartyContextLookupFunction<String> {
+ /** Logger. */
+ @Nonnull
+ private final Logger log = LoggerFactory.getLogger(LoginHintLookupStrategy.class);
+
/** {@inheritDoc} */
- @Nullable public String apply(final MessageContext messageCtx) {
+ @Nullable
+ public String apply(final MessageContext messageCtx) {
final DDF input = getDDF(messageCtx, DDFDirection.INPUT);
if (input == null) {
return null;
}
- return input.getmember(OIDCInitiatorConstants.LOGIN_HINT).string();
+
+ final String loginHint = input.getmember(OIDCInitiatorConstants.LOGIN_HINT).string();
+
+ if (loginHint != null) {
+ if (isFeatureDisallowed(OIDCAuthorizationConfiguration.FEATURE_LOGIN_HINT, messageCtx)) {
+ log.warn("Agent disallowed from setting the login_hint");
+ return null;
+ }
+ return loginHint;
+ }
+
+ final OIDCAuthenticationRelyingPartyProfileConfiguration rpConfig = getOIDCRelyingPartyProfileConfiguration(
+ messageCtx);
+
+ return rpConfig != null ? rpConfig.getLoginHint(PRC_LOOKUP.apply(messageCtx)) : null;
+
}
}
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/MaxAgeLookupStrategy.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/MaxAgeLookupStrategy.java
index 0f00321..3f9b409 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/MaxAgeLookupStrategy.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/MaxAgeLookupStrategy.java
@@ -20,11 +20,17 @@ import javax.annotation.Nullable;
import org.opensaml.messaging.context.MessageContext;
+import net.shibboleth.oidc.profile.config.OIDCAuthenticationRelyingPartyProfileConfiguration;
import net.shibboleth.sp.ddf.DDF;
import net.shibboleth.sp.oidc.profile.OIDCInitiatorConstants;
/**
- * Retrieve the max_age parameter from the {@link DDF}.
+ * Retrieve the max_age parameter from the {@link DDF} if present.
+ *
+ * <p>
+ * If the parameter is not present in the {@link DDF}, the method falls back to
+ * using the the relying party profile configuration.
+ * </p>
*/
public class MaxAgeLookupStrategy extends AbstractAgentAndRelyingPartyContextLookupFunction<Duration> {
@@ -35,10 +41,14 @@ public class MaxAgeLookupStrategy extends AbstractAgentAndRelyingPartyContextLoo
return null;
}
final Long maxAge = input.getmember(OIDCInitiatorConstants.MAX_AGE).longinteger();
- if (maxAge == null) {
- return null;
+ if (maxAge != null) {
+ return Duration.ofSeconds(maxAge);
}
- return Duration.ofSeconds(maxAge);
+ final OIDCAuthenticationRelyingPartyProfileConfiguration rpConfig = getOIDCRelyingPartyProfileConfiguration(
+ messageCtx);
+
+ return rpConfig != null ? rpConfig.getMaxAuthenticationAge(PRC_LOOKUP.apply(messageCtx)) : null;
+
}
}
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ResponseModeLookupStrategy.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ResponseModeLookupStrategy.java
index d9e8f1b..44e67e4 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ResponseModeLookupStrategy.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ResponseModeLookupStrategy.java
@@ -21,12 +21,9 @@ import org.opensaml.messaging.context.MessageContext;
import com.nimbusds.oauth2.sdk.ResponseMode;
import net.shibboleth.oidc.profile.config.OIDCAuthenticationRelyingPartyProfileConfiguration;
-import net.shibboleth.profile.context.RelyingPartyContext;
/**
- * A lookup strategy that resolves an OpenID Connect {@link ResponseMode} from the current {@link MessageContext}.
- * <p>
- * This strategy inspects the active {@link RelyingPartyContext} and its associated
+ * A lookup strategy that resolves an OpenID Connect {@link ResponseMode} from the
* {@link OIDCAuthenticationRelyingPartyProfileConfiguration}. If a response mode
* is configured in the relying party profile, it is parsed into a known
* {@link ResponseMode} value. If no configuration is available or the configured
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ResponseTypeLookupStrategy.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ResponseTypeLookupStrategy.java
index 1d3a910..553a071 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ResponseTypeLookupStrategy.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/ResponseTypeLookupStrategy.java
@@ -24,15 +24,9 @@ import org.opensaml.profile.context.navigate.ParentProfileRequestContextLookup;
import com.nimbusds.oauth2.sdk.ResponseType;
import net.shibboleth.oidc.profile.config.OIDCAuthenticationRelyingPartyProfileConfiguration;
-import net.shibboleth.profile.context.RelyingPartyContext;
/**
- * A lookup strategy that resolves the {@link ResponseType} to use
- * for a relying party, based the {@link OIDCAuthenticationRelyingPartyProfileConfiguration}.
- *
- * A lookup strategy that resolves an OpenID Connect {@link ResponseType} from the current {@link MessageContext}.
- * <p>
- * This strategy inspects the active {@link RelyingPartyContext} and its associated
+ * A lookup strategy that resolves an OpenID Connect {@link ResponseType} from the
* {@link OIDCAuthenticationRelyingPartyProfileConfiguration}. If a response type
* is configured in the relying party profile, it is parsed into a known
* {@link ResponseType} value. If no configuration is available or the configured
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/SetAuthenticationRequestTimeHandler.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/request/impl/SetAuthenticationRequestTimeHandler.java
similarity index 90%
rename from sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/SetAuthenticationRequestTimeHandler.java
rename to sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/request/impl/SetAuthenticationRequestTimeHandler.java
index 51bdeba..7d92943 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/SetAuthenticationRequestTimeHandler.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/request/impl/SetAuthenticationRequestTimeHandler.java
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-package net.shibboleth.sp.oidc.profile.impl;
+package net.shibboleth.sp.oidc.profile.request.impl;
import java.time.Instant;
@@ -23,6 +23,7 @@ import org.opensaml.messaging.handler.MessageHandlerException;
import org.slf4j.Logger;
import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.sp.oidc.profile.impl.AbstractAuthenticationRequestParameterValueMessageHandler;
/** Handler that adds the authentication request time to the authentication request.*/
diff --git a/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/AbstractAuthenticationLookupStrategyTest.java b/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/AbstractAuthenticationLookupStrategyTest.java
new file mode 100644
index 0000000..8f10c41
--- /dev/null
+++ b/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/AbstractAuthenticationLookupStrategyTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.oidc.profile.impl;
+
+import java.nio.charset.StandardCharsets;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.springframework.webflow.execution.RequestContext;
+import org.testng.annotations.BeforeMethod;
+
+import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
+import net.shibboleth.idp.profile.testing.RequestContextBuilder;
+import net.shibboleth.oidc.profile.config.impl.DefaultOIDCAuthorizationConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.sp.context.AgentRequestContext;
+import net.shibboleth.sp.ddf.DDF;
+
+/**
+ * An abstract test class for lookup functions that work to build authentication requests.
+ */
+public abstract class AbstractAuthenticationLookupStrategyTest {
+
+ /** Resource URL. */
+ @Nonnull
+ public static final byte[] RESOURCE_URL = "https://sp.example.org/secure".getBytes(StandardCharsets.UTF_8);
+
+ /** REDIRECT URI. */
+ @Nonnull
+ public static final String RESPONSE_URL = "https://sp.example.org/Shibboleth.sso/callback";
+
+ protected RequestContext rc;
+ protected MessageContext mc;
+ protected AuthenticationContext ac;
+ protected ProfileRequestContext prc;
+ protected RelyingPartyContext rpc;
+ protected AgentRequestContext arc;
+ protected RelyingPartyContext partyContext;
+
+ /** The RP config.*/
+ protected DefaultOIDCAuthorizationConfiguration rpConfig;
+
+ @BeforeMethod
+ public void setUp() throws ComponentInitializationException {
+ rc = new RequestContextBuilder().buildRequestContext();
+ prc = new WebflowRequestContextProfileRequestContextLookup().apply(rc);
+ ac = prc.ensureSubcontext(AuthenticationContext.class);
+ mc = new MessageContext();
+ prc.setOutboundMessageContext(mc);
+ arc = new AgentRequestContext();
+ prc.addSubcontext(arc);
+
+ partyContext = prc.ensureSubcontext(RelyingPartyContext.class);
+ rpConfig = new DefaultOIDCAuthorizationConfiguration();
+ partyContext.setProfileConfig(rpConfig);
+ prc.addSubcontext(partyContext);
+ }
+
+ /**
+ * Add the {@link DDF} to the agent request context.
+ *
+ * @param input the {@link DDF} to add.
+ */
+ protected void addDDFToAgentRequestContext(final DDF input) {
+ arc.setInput(input);
+ }
+
+}
diff --git a/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/DisplayParameterLookupStrategyTest.java b/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/DisplayParameterLookupStrategyTest.java
new file mode 100644
index 0000000..49dcf72
--- /dev/null
+++ b/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/DisplayParameterLookupStrategyTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.oidc.profile.impl;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.sp.ddf.DDF;
+import net.shibboleth.sp.messaging.RemotedHttpServletRequest;
+import net.shibboleth.sp.oidc.profile.OIDCInitiatorConstants;
+import net.shibboleth.sp.profile.InitiatorConstants;
+import net.shibboleth.sp.profile.SPConstants;
+
+/**
+ * Tests for {@link DisplayParameterLookupStrategy}.
+ */
+public class DisplayParameterLookupStrategyTest extends AbstractAuthenticationLookupStrategyTest {
+
+ /** The strategy to test.*/
+ private DisplayParameterLookupStrategy strategy;
+
+ /** The DDF to store input parameters.*/
+ private DDF ddf;
+
+ @Override
+ @BeforeMethod
+ public void setUp() throws ComponentInitializationException {
+ super.setUp();
+ strategy = new DisplayParameterLookupStrategy();
+
+ ddf = new DDF(null).structure();
+ ddf.addmember(RemotedHttpServletRequest.STRUCTURE_NAME).structure();
+ ddf.addmember(InitiatorConstants.RESPONSE_URL).string(RESPONSE_URL);
+ ddf.addmember(SPConstants.TARGET).unsafe_string(RESOURCE_URL);
+ addDDFToAgentRequestContext(ddf);
+ }
+
+
+ @Test
+ public void testDisplayParameterPresent() {
+ ddf.addmember(OIDCInitiatorConstants.DISPLAY).string("page");
+ final String result = strategy.apply(mc);
+ assertNotNull(result);
+ assert result != null;
+ assertEquals(result, "page");
+ }
+
+
+ @Test
+ public void testDisplayParameterMissingUsesRpConfig() {
+ rpConfig.setDisplay("popup");
+ final String result = strategy.apply(mc);
+ assertNotNull(result);
+ assert result != null;
+ assertEquals(result, "popup");
+ }
+
+ @Test
+ public void testDisplayParameterMissingNoRpConfig() {
+ prc.removeSubcontext(partyContext);
+ final String result = strategy.apply(mc);
+ assertNull(result);
+ }
+
+
+
+}
diff --git a/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/ForceAuthnParameterLookupStrategyTest.java b/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/ForceAuthnParameterLookupStrategyTest.java
new file mode 100644
index 0000000..ee437b0
--- /dev/null
+++ b/sp-oidc-impl/src/test/java/net/shibboleth/sp/oidc/profile/impl/ForceAuthnParameterLookupStrategyTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.oidc.profile.impl;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.sp.ddf.DDF;
+import net.shibboleth.sp.messaging.RemotedHttpServletRequest;
+import net.shibboleth.sp.oidc.profile.OIDCInitiatorConstants;
+import net.shibboleth.sp.profile.InitiatorConstants;
+import net.shibboleth.sp.profile.SPConstants;
+
+/**
+ * Tests for {@link ForceAuthnParameterLookupStrategy}.
+ */
+public class ForceAuthnParameterLookupStrategyTest extends AbstractAuthenticationLookupStrategyTest {
+
+ /** The strategy to test.*/
+ private ForceAuthnParameterLookupStrategy strategy;
+
+ /** The DDF to store input parameters.*/
+ private DDF ddf;
+
+ @Override
+ @BeforeMethod
+ public void setUp() throws ComponentInitializationException {
+ super.setUp();
+ strategy = new ForceAuthnParameterLookupStrategy();
+
+ ddf = new DDF(null).structure();
+ ddf.addmember(RemotedHttpServletRequest.STRUCTURE_NAME).structure();
+ ddf.addmember(InitiatorConstants.RESPONSE_URL).string(RESPONSE_URL);
+ ddf.addmember(SPConstants.TARGET).unsafe_string(RESOURCE_URL);
+ addDDFToAgentRequestContext(ddf);
+ }
+
+ @Test
+ public void testForceAuthnSetToOne() {
+ ddf.addmember(OIDCInitiatorConstants.FORCE_AUTHN).integer(1);
+ final Boolean result = strategy.apply(mc);
+ assertNotNull(result);
+ assert result != null;
+ assertTrue(result);
+ }
+
+ @Test
+ public void testForceAuthnSetToZero() {
+ ddf.addmember(OIDCInitiatorConstants.FORCE_AUTHN).integer(0);
+ final Boolean result = strategy.apply(mc);
+ assertNotNull(result);
+ assert result != null;
+ assertFalse(result);
+ }
+
+ @Test
+ public void testForceAuthnDisallowed() {
+ ddf.addmember(OIDCInitiatorConstants.FORCE_AUTHN).integer(1);
+ rpConfig.setDisallowedFeatures(OIDCAuthorizationConfiguration.FEATURE_FORCEAUTHN);
+ final Boolean result = strategy.apply(mc);
+ assertNotNull(result);
+ assert result != null;
+ assertFalse(result);
+ }
+
+
+ @Test
+ public void testForceAuthnNotPresentUsesRpConfig() {
+ rpConfig.setForceAuthn(true);
+ final Boolean result = strategy.apply(mc);
+ assertNotNull(result);
+ assert result != null;
+ assertTrue(result);
+ }
+
+
+ @Test
+ public void testForceAuthnNotPresentNoRpConfig() {
+ prc.removeSubcontext(partyContext);
+ final Boolean result = strategy.apply(mc);
+ assertNotNull(result);
+ assert result != null;
+ assertFalse(result);
+ }
+
+
+
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list