[java-identity-provider] branch main updated: IDP-2074 - Audit logging of chained password validators is broken
Scott Cantor
cantor.2 at osu.edu
Tue Apr 18 13:55:30 UTC 2023
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=883530bcadc896a14fc7c3f424e15a0ac4bee413
The following commit(s) were added to refs/heads/main by this push:
new 883530bca IDP-2074 - Audit logging of chained password validators is broken
883530bca is described below
commit 883530bcadc896a14fc7c3f424e15a0ac4bee413
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Apr 18 09:55:26 2023 -0400
IDP-2074 - Audit logging of chained password validators is broken
https://shibboleth.atlassian.net/browse/IDP-2074
Adjusted context APIs to allow tracking of last error/warning.
Removed Spring-based handling of AR audit field.
Manually added AR field to audit context via auditing validation action.
---
.../idp/authn/AbstractValidationAction.java | 11 +-
.../authn/context/AuthenticationErrorContext.java | 48 ++--
.../context/AuthenticationWarningContext.java | 33 ++-
.../impl/AuthenticationErrorAuditExtractor.java | 56 -----
.../impl/AbstractAuditingValidationAction.java | 33 ++-
.../idp/flows/authn/authn-abstract-beans.xml | 6 -
.../src/test/resources/conf/authn/authn.properties | 243 +++++++++++++++++++++
7 files changed, 334 insertions(+), 96 deletions(-)
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractValidationAction.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractValidationAction.java
index 7b6a3df52..7e3a0ac22 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractValidationAction.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractValidationAction.java
@@ -528,8 +528,7 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
if (Iterables.any(entry.getValue(), checker::test)) {
final String key = entry.getKey();
assert key!=null;
- authenticationContext.ensureSubcontext(
- AuthenticationErrorContext.class).getClassifiedErrors().add(key);
+ authenticationContext.ensureSubcontext(AuthenticationErrorContext.class).addClassifiedError(key);
if (!eventSet) {
eventSet = true;
ActionSupport.buildEvent(profileRequestContext, key);
@@ -539,8 +538,7 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
}
if (!eventSet) {
- authenticationContext.ensureSubcontext(
- AuthenticationErrorContext.class).getClassifiedErrors().add(eventId);
+ authenticationContext.ensureSubcontext(AuthenticationErrorContext.class).addClassifiedError(eventId);
ActionSupport.buildEvent(profileRequestContext, eventId);
}
}
@@ -575,7 +573,7 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
final String key = entry.getKey();
assert key!=null;
authenticationContext.ensureSubcontext(
- AuthenticationWarningContext.class).getClassifiedWarnings().add(key);
+ AuthenticationWarningContext.class).addClassifiedWarning(key);
if (!eventSet) {
eventSet = true;
ActionSupport.buildEvent(profileRequestContext, key);
@@ -585,8 +583,7 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
}
if (!eventSet) {
- authenticationContext.ensureSubcontext(
- AuthenticationWarningContext.class).getClassifiedWarnings().add(eventId);
+ authenticationContext.ensureSubcontext(AuthenticationWarningContext.class).addClassifiedWarning(eventId);
ActionSupport.buildEvent(profileRequestContext, eventId);
}
}
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationErrorContext.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationErrorContext.java
index 80a7b3570..fe4eff372 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationErrorContext.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationErrorContext.java
@@ -19,15 +19,15 @@ package net.shibboleth.idp.authn.context;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.shared.annotation.constraint.Live;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.logic.Constraint;
import org.opensaml.messaging.context.BaseContext;
@@ -53,7 +53,7 @@ public final class AuthenticationErrorContext extends BaseContext {
/** Constructor. */
public AuthenticationErrorContext() {
exceptions = new ArrayList<>();
- classifiedErrors = new HashSet<>();
+ classifiedErrors = new LinkedHashSet<>();
}
/**
@@ -65,20 +65,6 @@ public final class AuthenticationErrorContext extends BaseContext {
return exceptions;
}
- /**
- * Add an exception to the list.
- *
- * @param e exception to add
- *
- * @deprecated
- */
- @Deprecated(forRemoval=true, since="4.0.0")
- public void addException(@Nonnull final Exception e) {
- Constraint.isNotNull(e, "Exception cannot be null");
-
- exceptions.add(e);
- }
-
/**
* Get a mutable collection of error "tokens" associated with the context.
*
@@ -98,4 +84,32 @@ public final class AuthenticationErrorContext extends BaseContext {
return classifiedErrors.contains(error);
}
+ /**
+ * Adds a classified error to the context, ensuring that it will be returned
+ * from {@link #getLastClassifiedError()} until another is added.
+ *
+ * @param error error to add
+ *
+ * @return this context
+ *
+ * @since 5.0.0
+ */
+ @Nonnull public AuthenticationErrorContext addClassifiedError(@Nonnull @NotEmpty final String error) {
+ // This is done to preserve ordering so that the error is the "last one added".
+ classifiedErrors.remove(error);
+ classifiedErrors.add(error);
+ return this;
+ }
+
+ /**
+ * Gets the last classified error added, or null if none.
+ *
+ * @return last error added or null
+ *
+ * @since 5.0.0
+ */
+ @Nullable public String getLastClassifiedError() {
+ return classifiedErrors.stream().reduce((first, second) -> second).orElse(null);
+ }
+
}
\ No newline at end of file
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationWarningContext.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationWarningContext.java
index 13a39bd83..0963dbbc6 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationWarningContext.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationWarningContext.java
@@ -18,9 +18,10 @@
package net.shibboleth.idp.authn.context;
import java.util.Collection;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opensaml.messaging.context.BaseContext;
@@ -46,7 +47,7 @@ public final class AuthenticationWarningContext extends BaseContext {
/** Constructor. */
public AuthenticationWarningContext() {
- classifiedWarnings = new HashSet<>();
+ classifiedWarnings = new LinkedHashSet<>();
}
/**
@@ -68,4 +69,32 @@ public final class AuthenticationWarningContext extends BaseContext {
return classifiedWarnings.contains(warning);
}
+ /**
+ * Adds a classified warning to the context, ensuring that it will be returned
+ * from {@link #getLastClassifiedWarning()} until another is added.
+ *
+ * @param warning warning to add
+ *
+ * @return this context
+ *
+ * @since 5.0.0
+ */
+ @Nonnull public AuthenticationWarningContext addClassifiedWarning(@Nonnull @NotEmpty final String warning) {
+ // This is done to preserve ordering so that the error is the "last one added".
+ classifiedWarnings.remove(warning);
+ classifiedWarnings.add(warning);
+ return this;
+ }
+
+ /**
+ * Gets the last classified warning added, or null if none.
+ *
+ * @return last warning added or null
+ *
+ * @since 5.0.0
+ */
+ @Nullable public String getLastClassifiedWarning() {
+ return classifiedWarnings.stream().reduce((first, second) -> second).orElse(null);
+ }
+
}
\ No newline at end of file
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/audit/impl/AuthenticationErrorAuditExtractor.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/audit/impl/AuthenticationErrorAuditExtractor.java
deleted file mode 100644
index f6b09870e..000000000
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/audit/impl/AuthenticationErrorAuditExtractor.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.authn.audit.impl;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.function.Function;
-
-import javax.annotation.Nullable;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-
-import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.idp.authn.context.AuthenticationErrorContext;
-
-/**
- * {@link Function} that returns any classified errors found in a subordinate {@link AuthenticationErrorContext},
- * or "Success" if none.
- *
- * @since 4.3.0
- */
-public class AuthenticationErrorAuditExtractor implements Function<ProfileRequestContext,Collection<String>> {
-
- /** {@inheritDoc} */
- @Nullable public Collection<String> apply(@Nullable final ProfileRequestContext input) {
-
- assert input != null;
- final AuthenticationContext authnCtx = input.getSubcontext(AuthenticationContext.class);
- if (authnCtx != null) {
- final AuthenticationErrorContext errorCtx = authnCtx.getSubcontext(AuthenticationErrorContext.class);
- if (errorCtx != null) {
- return errorCtx.getClassifiedErrors();
- }
-
- return Collections.singletonList("Success");
- }
-
- return null;
- }
-
-}
\ No newline at end of file
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/AbstractAuditingValidationAction.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/AbstractAuditingValidationAction.java
index 7592bbe57..ad3a76a55 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/AbstractAuditingValidationAction.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/AbstractAuditingValidationAction.java
@@ -30,7 +30,9 @@ import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import net.shibboleth.idp.authn.AbstractValidationAction;
+import net.shibboleth.idp.authn.AuthnAuditFields;
import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.authn.context.AuthenticationErrorContext;
import net.shibboleth.idp.profile.audit.impl.PopulateAuditContext;
import net.shibboleth.idp.profile.audit.impl.WriteAuditLog;
import net.shibboleth.profile.context.AuditContext;
@@ -114,14 +116,14 @@ public abstract class AbstractAuditingValidationAction extends AbstractValidatio
/** {@inheritDoc} */
@Override
protected void recordSuccess(@Nonnull final ProfileRequestContext profileRequestContext) {
- doAudit(profileRequestContext);
+ doAudit(profileRequestContext, true);
super.recordSuccess(profileRequestContext);
}
/** {@inheritDoc} */
@Override
protected void recordFailure(@Nonnull final ProfileRequestContext profileRequestContext) {
- doAudit(profileRequestContext);
+ doAudit(profileRequestContext, false);
super.recordFailure(profileRequestContext);
}
@@ -136,12 +138,14 @@ public abstract class AbstractAuditingValidationAction extends AbstractValidatio
return auditContextCreationStrategy.apply(profileRequestContext);
}
+// Checkstyle: CyclomaticComplexity OFF
/**
* Do audit extraction and output.
*
* @param profileRequestContext profile request context
+ * @param success true iff this is an audit of successful validation
*/
- protected void doAudit(@Nonnull final ProfileRequestContext profileRequestContext) {
+ protected void doAudit(@Nonnull final ProfileRequestContext profileRequestContext, final boolean success) {
if (populateAuditContextAction != null && writeAuditLogAction != null) {
final EventContext existingEvent = profileRequestContext.getSubcontext(EventContext.class);
@@ -149,17 +153,29 @@ public abstract class AbstractAuditingValidationAction extends AbstractValidatio
try {
assert populateAuditContextAction != null;
populateAuditContextAction.execute(requestContext);
-
- final Map<String,String> fields = getAuditFields(profileRequestContext);
- if (fields != null) {
- final AuditContext ac = getAuditContext(profileRequestContext);
- if (ac != null) {
+
+ final AuditContext ac = getAuditContext(profileRequestContext);
+ if (ac != null) {
+ final Map<String,String> fields = getAuditFields(profileRequestContext);
+ if (fields != null) {
for (final Map.Entry<String,String> field : fields.entrySet()) {
final String key = field.getKey();
assert key != null;
ac.getFieldValues(key).add(field.getValue());
}
}
+
+ // Manual handling of "result" field.
+ if (success) {
+ ac.getFields().put(AuthnAuditFields.AUTHN_RESULT, "Success");
+ } else {
+ final AuthenticationErrorContext errorContext =
+ profileRequestContext.ensureSubcontext(AuthenticationContext.class)
+ .getSubcontext(AuthenticationErrorContext.class);
+ if (errorContext != null) {
+ ac.getFields().put(AuthnAuditFields.AUTHN_RESULT, errorContext.getLastClassifiedError());
+ }
+ }
}
} finally {
if (existingEvent != null) {
@@ -177,6 +193,7 @@ public abstract class AbstractAuditingValidationAction extends AbstractValidatio
}
}
}
+// Checkstyle: CyclomaticComplexity ON
/**
* Subclasses can override this method to supply additional audit fields to store.
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/authn-abstract-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/authn-abstract-beans.xml
index b511f0e2a..7207955f5 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/authn-abstract-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/authn-abstract-beans.xml
@@ -68,12 +68,6 @@
</key>
<bean class="net.shibboleth.idp.authn.audit.impl.AttemptedAuthenticationFlowAuditExtractor" />
</entry>
- <entry>
- <key>
- <util:constant static-field="net.shibboleth.idp.authn.AuthnAuditFields.AUTHN_RESULT"/>
- </key>
- <bean class="net.shibboleth.idp.authn.audit.impl.AuthenticationErrorAuditExtractor" />
- </entry>
<entry>
<key>
<util:constant static-field="net.shibboleth.idp.saml.profile.SAMLAuditFields.SERVICE_PROVIDER"/>
diff --git a/idp-conf/src/test/resources/conf/authn/authn.properties b/idp-conf/src/test/resources/conf/authn/authn.properties
new file mode 100644
index 000000000..6b029e14d
--- /dev/null
+++ b/idp-conf/src/test/resources/conf/authn/authn.properties
@@ -0,0 +1,243 @@
+# Properties that control authentication generally and the behavior of
+# specific methods.
+
+# Regular expression matching login flows to enable, e.g. IPAddress|Password
+#idp.authn.flows = Password
+
+# Default settings for most authentication methods.
+#idp.authn.defaultLifetime = PT1H
+#idp.authn.defaultTimeout = PT30M
+#idp.authn.proxyRestrictionsEnforced = true
+
+# Whether to populate relying party user interface information for display
+# during authentication, consent, terms-of-use.
+#idp.authn.rpui = true
+
+# Whether to prioritize "active" results when an SP requests more than
+# one possible matching login method (V2 behavior was to favor them)
+#idp.authn.favorSSO = false
+
+# Whether to fail requests when a user identity after authentication
+# doesn't match the identity in a pre-existing session.
+#idp.authn.identitySwitchIsError = false
+
+# If using IdP discovery feature, provides a discovery location to use.
+#idp.authn.discoveryURL = https://ds.example.org/shibboleth-ds/index.html
+
+# Login flow audit logging (defaults false for log compatibility)
+idp.authn.audit.enabled = true
+
+# Revocation (administrative logout)
+#idp.authn.revocation = false
+#idp.authn.revocation.lifetime = %{idp.authn.defaultAuthnLifetime:PT12H}
+# Name of BiCondition to apply for check
+#idp.authn.revocation.Condition = shibboleth.RevocationCacheCondition
+# Set to true to treat lookup failures as being revoked.
+#idp.authn.revocation.strict = false
+# Set to true to check for address-based revocation.
+#idp.authn.revocation.addressBased = false
+# Default implementation based on a StorageService bean.
+#idp.authn.revocation.cache = shibboleth.AuthnRevocationCache
+#idp.authn.revocation.StorageService = shibboleth.StorageService
+
+
+# Properties below override specific method behavior, as an alternative
+# to defining Spring beans in XML. Refer to the documentation for a complete
+# list. Many of the properties below are mentioned only because they are
+# atypical defaults assumed for a given method.
+
+# Flow selection among multiple equivalent options can be managed with
+# the order properties, lower will be tried first.
+
+#### Password ####
+
+#idp.authn.Password.order = 1000
+#idp.authn.Password.passiveAuthenticationSupported = true
+#idp.authn.Password.forcedAuthenticationSupported = true
+# Override this and removeAfterValidation to require all validators to succeed
+#idp.authn.Password.requireAll = false
+# Override to keep the password around
+#idp.authn.Password.removeAfterValidation = true
+# Override to store password in Java Subject
+#idp.authn.Password.retainAsPrivateCredential = false
+# Simple username transforms before validation
+#idp.authn.Password.trim = true
+#idp.authn.Password.lowercase = false
+#idp.authn.Password.uppercase = false
+#idp.authn.Password.matchExpression =
+# Override default form field names
+#idp.authn.Password.usernameFieldName = j_username
+#idp.authn.Password.passwordFieldName = j_password
+#idp.authn.Password.ssoBypassFieldName = donotcache
+# Unset if using customized Principals per validator
+#idp.authn.Password.addDefaultPrincipals = true
+# The Principal collection below is the typical default if not otherwise noted.
+#idp.authn.Password.supportedPrincipals = \
+# saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \
+# saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \
+# saml1/urn:oasis:names:tc:SAML:1.0:am:password
+# Validators are controlled in password-authn-config.xml
+
+#### Password Backends ####
+
+# See ldap.properties for LDAP authn properties
+# Kerberos settings
+#idp.authn.Krb5.refreshConfig = false
+#idp.authn.Krb5.preserveTicket = false
+# Set next two for KDC verification
+#idp.authn.Krb5.servicePrincipal =
+#idp.authn.Krb5.keytab =
+# JAAS settings
+#idp.authn.JAAS.loginConfigNames = ShibUserPassAuth
+#idp.authn.JAAS.loginConfig = %{idp.home}/conf/authn/jaas.config
+
+#### External ####
+
+#idp.authn.External.order = 1000
+#idp.authn.External.nonBrowserSupported = false
+#idp.authn.External.matchExpression =
+# Unset if you plan to return full Java Subject from external source
+#idp.authn.External.addDefaultPrincipals = true
+# Servlet context-relative path to wherever your implementation lives
+idp.authn.External.externalAuthnPath = contextRelative:external.jsp
+
+#### RemoteUser ####
+
+#idp.authn.RemoteUser.order = 1000
+#idp.authn.RemoteUser.nonBrowserSupported = false
+#idp.authn.RemoteUser.matchExpression =
+# Unset in most cases only if using the authnMethodHeader or
+# subjectAttribute settings
+#idp.authn.RemoteUser.addDefaultPrincipals = true
+#idp.authn.RemoteUser.checkRemoteUser = true
+# Comma-delimited lists of attributes or headers to pull from
+#idp.authn.RemoteUser.checkAttributes =
+#idp.authn.RemoteUser.checkHeaders =
+# Advanced settings
+#idp.authn.RemoteUser.subjectAttribute =
+#idp.authn.RemoteUser.authnMethodHeader =
+#idp.authn.RemoteUser.authnAuthorityHeader =
+
+#### RemoteUserInternal ####
+
+#idp.authn.RemoteUserInternal.order = 1000
+#idp.authn.RemoteUserInternal.nonBrowserSupported = true
+# Unset in most cases only if using the authnMethodHeader feature
+#idp.authn.RemoteUserInternal.addDefaultPrincipals = true
+#idp.authn.RemoteUserInternal.checkRemoteUser = true
+# Comma-delimited lists of attributes or headers to pull from
+#idp.authn.RemoteUserInternal.checkAttributes =
+#idp.authn.RemoteUserInternal.checkHeaders =
+# Simple transforms to apply
+#idp.authn.RemoteUserInternal.trim = true
+#idp.authn.RemoteUserInternal.lowercase = false
+#idp.authn.RemoteUserInternal.uppercase = false
+#idp.authn.RemoteUserInternal.matchExpression =
+#idp.authn.RemoteUserInternal.allowedUsernames =
+#idp.authn.RemoteUserInternal.deniedUsernames =
+
+#### SPNEGO ####
+
+#idp.authn.SPNEGO.order = 1000
+#idp.authn.SPNEGO.nonBrowserSupported = false
+#idp.authn.SPNEGO.enforceRun = false
+#idp.authn.SPNEGO.refreshKrbConfig = false
+#idp.authn.SPNEGO.matchExpression =
+idp.authn.SPNEGO.supportedPrincipals = \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos, \
+ saml1/urn:ietf:rfc:1510
+
+#### X509 ####
+
+#idp.authn.X509.order = 1000
+#idp.authn.X509.nonBrowserSupported = false
+#idp.authn.X509.saveCertificateToCredentialSet = true
+# Servlet context-relative path to wherever your implementation lives
+#idp.authn.X509.externalAuthnPath = contextRelative:x509-prompt.jsp
+idp.authn.X509.supportedPrincipals = \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:X509, \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient, \
+ saml1/urn:ietf:rfc:2246
+
+#### X509Internal ####
+
+#idp.authn.X509Internal.order = 1000
+#idp.authn.X509Internal.nonBrowserSupported = false
+#idp.authn.X509Internal.saveCertificateToCredentialSet = true
+idp.authn.X509Internal.supportedPrincipals = \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:X509, \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient, \
+ saml1/urn:ietf:rfc:2246
+
+#### IPAddress ####
+
+#idp.authn.IPAddress.order = 1000
+#idp.authn.IPAddress.passiveAuthenticationSupported = true
+#idp.authn.IPAddress.lifetime = PT60S
+#idp.authn.IPAddress.inactivityTimeout = PT60S
+idp.authn.IPAddress.supportedPrincipals = \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol
+
+#### Function ####
+
+#idp.authn.Function.order = 1000
+#idp.authn.Function.passiveAuthenticationSupported = true
+# Unset if you plan to return full Java Subject from function
+#idp.authn.Function.addDefaultPrincipals = true
+
+#### Duo ####
+
+#idp.authn.Duo.order = 1000
+#idp.authn.Duo.nonBrowserSupported = false
+#idp.authn.Duo.forcedAuthenticationSupported = true
+# Unset if you have advanced Duo integrations with individualized Principals
+#idp.authn.Duo.addDefaultPrincipals = true
+# The list below should be changed to reflect whatever locally- or
+# community-defined values are appropriate to represent Duo. It is
+# strongly advised that the value not be specific to Duo or any
+# particular technology to avoid lock-in.
+idp.authn.Duo.supportedPrincipals = \
+ saml2/http://example.org/ac/classes/mfa, \
+ saml1/http://example.org/ac/classes/mfa
+# Default Duo integration settings are defined separately
+# in duo.properties due to the sensitivity of the secret key.
+
+
+#### SAML ####
+
+#idp.authn.SAML.order = 1000
+#idp.authn.SAML.nonBrowserSupported = false
+#idp.authn.SAML.passiveAuthenticationSupported = true
+#idp.authn.SAML.forcedAuthenticationSupported = true
+#idp.authn.SAML.proxyScopingEnforced = true
+# Discovery options:
+# Define shibboleth.authn.SAML.discoveryFunction bean
+# Set proxyEntityID property
+# Fall through to discovery via discoveryRequired property
+#idp.authn.SAML.proxyEntityID = https://idp.example.org/idp/shibboleth
+#idp.authn.SAML.discoveryRequired = true
+# Generally left false with bidirectional mappings in
+# conf/authn/authn-comparison.xml across the proxy boundary.
+# Adjust as needed to reflect IdP's capabilities/support.
+#idp.authn.SAML.addDefaultPrincipals = false
+#idp.authn.SAML.supportedPrincipals = \
+# saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \
+# saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \
+# saml1/urn:oasis:names:tc:SAML:1.0:am:password
+
+#### MFA ####
+
+#idp.authn.MFA.order = 1000
+#idp.authn.MFA.passiveAuthenticationSupported = true
+#idp.authn.MFA.forcedAuthenticationSupported = true
+#idp.authn.MFA.validateLoginTransitions = true
+# The list below almost certainly requires changes, and should generally be the
+# union of any of the separate factors you combine in your particular MFA flow
+# rules. The example corresponds to the example in mfa-authn-config.xml that
+# combines IPAddress with Password.
+idp.authn.MFA.supportedPrincipals = \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol, \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \
+ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \
+ saml1/urn:oasis:names:tc:SAML:1.0:am:password
+# Most actual setup via mfa-authn-config.xml
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list