[java-identity-provider] branch maint-4 updated: IDP-2039 - Add audit logging to login flows
Scott Cantor
cantor.2 at osu.edu
Wed Dec 7 17:07:43 UTC 2022
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch maint-4
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=6d3b4b94185f98d1ecf58cb412af11836d445948
The following commit(s) were added to refs/heads/maint-4 by this push:
new 6d3b4b941 IDP-2039 - Add audit logging to login flows
6d3b4b941 is described below
commit 6d3b4b94185f98d1ecf58cb412af11836d445948
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Dec 7 12:07:40 2022 -0500
IDP-2039 - Add audit logging to login flows
https://shibboleth.atlassian.net/browse/IDP-2039
Finish adding to Function and SPNEGO flows.
Adjust Function flow with better behavior.
Remove extraneous message mappings.
---
.../idp/authn/impl/RemoteUserAuthServlet.java | 12 +---
.../authn/impl/ValidateExternalAuthentication.java | 65 +++++++++++++---------
.../idp/authn/impl/ValidateFunctionResult.java | 60 +++++++++++++++++---
.../shibboleth/idp/flows/authn/duo-authn-beans.xml | 11 ----
.../idp/flows/authn/external-authn-beans.xml | 22 +++++++-
.../idp/flows/authn/function-authn-beans.xml | 23 +++++++-
.../idp/flows/authn/ipaddress-authn-beans.xml | 19 -------
.../idp/flows/authn/password-authn-beans.xml | 9 ---
.../idp/flows/authn/remoteuser-authn-beans.xml | 31 +----------
.../authn/remoteuser-internal-authn-beans.xml | 19 -------
.../idp/flows/authn/spnego-authn-beans.xml | 36 +++++++++---
.../idp/flows/authn/x509-internal-authn-beans.xml | 14 -----
.../module/conf/authn/external-authn-config.xml | 21 +------
.../module/conf/authn/function-authn-config.xml | 3 +
.../idp/module/conf/authn/spnego-authn-config.xml | 20 -------
15 files changed, 171 insertions(+), 194 deletions(-)
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/RemoteUserAuthServlet.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/RemoteUserAuthServlet.java
index b287cb47c..e0ba20aa4 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/RemoteUserAuthServlet.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/RemoteUserAuthServlet.java
@@ -39,7 +39,6 @@ import net.shibboleth.idp.authn.AuthenticationFlowDescriptor;
import net.shibboleth.idp.authn.ExternalAuthentication;
import net.shibboleth.idp.authn.ExternalAuthenticationException;
import net.shibboleth.idp.authn.context.AuthenticationContext;
-import net.shibboleth.idp.authn.context.UsernameContext;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
@@ -189,7 +188,8 @@ public class RemoteUserAuthServlet extends HttpServlet {
}
}
- param = config.getInitParameter(CHECK_HEADERS_PARAM);
+ //param = config.getInitParameter(CHECK_HEADERS_PARAM);
+ param = "ShibbolethUser";
if (param != null) {
final String[] headers = param.split(" ");
if (headers != null) {
@@ -284,14 +284,6 @@ public class RemoteUserAuthServlet extends HttpServlet {
return;
}
- // Populate the username into a UsernameContext for auditing.
- final ProfileRequestContext prc = ExternalAuthentication.getProfileRequestContext(key, httpRequest);
- final AuthenticationContext authnCtx = prc.getSubcontext(AuthenticationContext.class);
- if (authnCtx != null) {
- final UsernameContext uc = authnCtx.getSubcontext(UsernameContext.class, true);
- uc.setUsername(username);
- }
-
if (authnAuthorityHeader != null) {
// Check for proxied authorities.
final Enumeration<String> authorities = httpRequest.getHeaders(authnAuthorityHeader);
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
index 546fde4ae..e225ca9a7 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
@@ -18,6 +18,7 @@
package net.shibboleth.idp.authn.impl;
import java.util.Collections;
+import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.regex.Pattern;
@@ -38,10 +39,10 @@ import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.authn.context.CertificateContext;
import net.shibboleth.idp.authn.context.ExternalAuthenticationContext;
-import net.shibboleth.idp.authn.context.UsernameContext;
import net.shibboleth.idp.authn.principal.IdPAttributePrincipal;
import net.shibboleth.idp.authn.principal.ProxyAuthenticationPrincipal;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
+import net.shibboleth.idp.profile.IdPAuditFields;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.service.ReloadableService;
@@ -262,23 +263,54 @@ public class ValidateExternalAuthentication extends AbstractAuditingValidationAc
private boolean checkUsername(@Nonnull final Subject subject) {
if (matchExpression != null) {
- final Set<UsernamePrincipal> princs = subject.getPrincipals(UsernamePrincipal.class);
- if (princs != null && !princs.isEmpty()) {
- if (matchExpression.matcher(princs.iterator().next().getName()).matches()) {
+ final String name = getUsername(subject);
+ if (name != null) {
+ if (matchExpression.matcher(name).matches()) {
return true;
}
- log.info("{} Username did not match expression", getLogPrefix());
+ log.info("{} Username {} did not match expression", getLogPrefix(), name);
return false;
}
- log.info("{} Match expression set, but not UsernamePrincipal found");
+ log.info("{} Match expression set, but no UsernamePrincipal found");
return false;
}
return true;
}
+ /**
+ * Get the username from a {@link UsernamePrincipal} inside the subject.
+ *
+ * @param subject input subject
+ *
+ * @return username, or null
+ */
+ @Nullable private String getUsername(@Nonnull final Subject subject) {
+
+ final Set<UsernamePrincipal> princs = subject.getPrincipals(UsernamePrincipal.class);
+ if (princs != null && !princs.isEmpty()) {
+ return princs.iterator().next().getName();
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable protected Map<String,String> getAuditFields(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (extContext != null && extContext.getSubject() != null) {
+ final String name = getUsername(extContext.getSubject());
+ if (name != null) {
+ return Collections.singletonMap(IdPAuditFields.USERNAME, name);
+ }
+ }
+
+ return super.getAuditFields(profileRequestContext);
+ }
+
/**
* Check for inbound attributes and apply filtering.
*/
@@ -350,27 +382,6 @@ public class ValidateExternalAuthentication extends AbstractAuditingValidationAc
filterContext.setAttributeIssuerID(extContext.getAuthenticatingAuthorities().iterator().next());
}
}
-
- /**
- * A default cleanup hook that removes a {@link UsernameContext} from the tree.
- *
- * @since 4.3.0
- */
- public static class UsernameCleanupHook implements Consumer<ProfileRequestContext> {
-
- /** {@inheritDoc} */
- public void accept(@Nullable final ProfileRequestContext input) {
- if (input != null) {
- final AuthenticationContext authnCtx = input.getSubcontext(AuthenticationContext.class);
- if (authnCtx != null) {
- final UsernameContext uCtx = authnCtx.getSubcontext(UsernameContext.class);
- if (uCtx != null) {
- authnCtx.removeSubcontext(uCtx);
- }
- }
- }
- }
- }
/**
* A default cleanup hook that removes a {@link CertificateContext} from the tree.
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateFunctionResult.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateFunctionResult.java
index 3af9d2d18..d774a09fc 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateFunctionResult.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateFunctionResult.java
@@ -18,16 +18,19 @@
package net.shibboleth.idp.authn.impl;
import java.security.Principal;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.security.auth.Subject;
-import net.shibboleth.idp.authn.AbstractValidationAction;
import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
+import net.shibboleth.idp.profile.IdPAuditFields;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@@ -35,7 +38,6 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
-import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
@@ -54,7 +56,7 @@ import org.slf4j.LoggerFactory;
*
* @since 3.4.0
*/
-public class ValidateFunctionResult extends AbstractValidationAction {
+public class ValidateFunctionResult extends AbstractAuditingValidationAction {
/** Default prefix for metrics. */
@Nonnull @NotEmpty private static final String DEFAULT_METRIC_NAME = "net.shibboleth.idp.authn.function";
@@ -101,11 +103,19 @@ public class ValidateFunctionResult extends AbstractValidationAction {
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
@Nonnull final AuthenticationContext authenticationContext) {
- result = resultLookupStrategy.apply(profileRequestContext);
+ try {
+ result = resultLookupStrategy.apply(profileRequestContext);
+ } catch (final Exception e) {
+ log.info("{} Authentication by function failed with exception", getLogPrefix(), e);
+ handleError(profileRequestContext, authenticationContext, e, AuthnEventIds.AUTHN_EXCEPTION);
+ recordFailure(profileRequestContext);
+ return;
+ }
if (result == null) {
log.info("{} Authentication by function failed", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
+ handleError(profileRequestContext, authenticationContext, AuthnEventIds.NO_CREDENTIALS,
+ AuthnEventIds.NO_CREDENTIALS);
recordFailure(profileRequestContext);
} else if (result instanceof String) {
log.info("{} Validated user via name '{}'", getLogPrefix(), result);
@@ -121,7 +131,8 @@ public class ValidateFunctionResult extends AbstractValidationAction {
buildAuthenticationResult(profileRequestContext, authenticationContext);
} else {
log.info("{} Authentication by function failed, result type was invalid", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_CREDENTIALS);
+ handleError(profileRequestContext, authenticationContext, AuthnEventIds.NO_CREDENTIALS,
+ AuthnEventIds.NO_CREDENTIALS);
recordFailure(profileRequestContext);
}
}
@@ -145,5 +156,40 @@ public class ValidateFunctionResult extends AbstractValidationAction {
// Save my walrus!
throw new ConstraintViolationException("Result type was unexpected");
}
-
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable protected Map<String,String> getAuditFields(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (result instanceof String) {
+ return Collections.singletonMap(IdPAuditFields.USERNAME, (String) result);
+ } else if (result instanceof UsernamePrincipal) {
+ return Collections.singletonMap(IdPAuditFields.USERNAME, ((UsernamePrincipal) result).getName());
+ } else if (result instanceof Subject) {
+ final String name = getUsername((Subject) result);
+ if (name != null) {
+ return Collections.singletonMap(IdPAuditFields.USERNAME, name);
+ }
+ }
+
+ return super.getAuditFields(profileRequestContext);
+ }
+
+ /**
+ * Get the username from a {@link UsernamePrincipal} inside the subject.
+ *
+ * @param subject input subject
+ *
+ * @return username, or null
+ */
+ @Nullable private String getUsername(@Nonnull final Subject subject) {
+
+ final Set<UsernamePrincipal> princs = subject.getPrincipals(UsernamePrincipal.class);
+ if (princs != null && !princs.isEmpty()) {
+ return princs.iterator().next().getName();
+ }
+
+ return null;
+ }
+
}
\ No newline at end of file
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/duo-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/duo-authn-beans.xml
index 2ee4feb9f..a32a5b94d 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/duo-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/duo-authn-beans.xml
@@ -44,22 +44,11 @@
<value>Your two-factor account is disabled.</value>
</list>
</entry>
- <entry key="RequestUnsupported">
- <list>
- <value>RequestUnsupported</value>
- </list>
- </entry>
<entry key="NoCredentials">
<list>
- <value>NoCredentials</value>
<value>Invalid request parameters (no capable device)</value>
</list>
</entry>
- <entry key="InvalidCredentials">
- <list>
- <value>InvalidCredentials</value>
- </list>
- </entry>
</util:map>
<!-- Can override one or more of the beans above. -->
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/external-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/external-authn-beans.xml
index 2b95f04a7..c82a36b66 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/external-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/external-authn-beans.xml
@@ -31,10 +31,30 @@
p:classifiedMessages="#{getObject('shibboleth.authn.External.ClassifiedMessageMap')}"
p:resultCachingPredicate="#{getObject('shibboleth.authn.External.resultCachingPredicate')}"
c:filterService-ref="shibboleth.AttributeFilterService"
- p:metadataResolver-ref="shibboleth.MetadataResolver" />
+ p:metadataResolver-ref="shibboleth.MetadataResolver"
+ p:populateAuditContextAction="#{%{idp.authn.External.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('shibboleth.authn.External.PopulateAuditContext') : null}"
+ p:writeAuditLogAction="#{%{idp.authn.External.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('WriteAuditLog') : null}" />
<bean id="PopulateSubjectCanonicalizationContext"
class="net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext" scope="prototype"
p:availableFlows-ref="shibboleth.PostLoginSubjectCanonicalizationFlows" />
+ <!-- Audit logging beans. -->
+
+ <util:map id="shibboleth.authn.AuditFormattingMap">
+ <entry key="#{'%{idp.authn.External.audit.category:Shibboleth-Audit.External}'.trim()}"
+ value="#{'%{idp.authn.External.audit.format:%a|%T|%SP|%s|%AF|%u|%AR|%UA}'.trim()}" />
+ </util:map>
+
+ <bean id="shibboleth.authn.External.DefaultAuditExtractors" parent="shibboleth.authn.DefaultAuditExtractors" lazy-init="true"
+ class="org.springframework.beans.factory.config.MapFactoryBean">
+ <property name="sourceMap">
+ <map merge="true" />
+ </property>
+ </bean>
+
+ <bean id="shibboleth.authn.External.PopulateAuditContext" parent="shibboleth.authn.AbstractPopulateAuditContext" lazy-init="true"
+ p:fieldExtractors="#{getObject('shibboleth.authn.External.AuditExtractors') ?: getObject('shibboleth.authn.External.DefaultAuditExtractors')}"
+ p:clearAuditContext="true" />
+
</beans>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/function-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/function-authn-beans.xml
index eb4140e76..93f8db662 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/function-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/function-authn-beans.xml
@@ -29,10 +29,31 @@
<bean id="ValidateFunctionResult" class="net.shibboleth.idp.authn.impl.ValidateFunctionResult" scope="prototype"
p:addDefaultPrincipals="#{getObject('shibboleth.authn.Function.addDefaultPrincipals') ?: %{idp.authn.Function.addDefaultPrincipals:true}}"
p:resultCachingPredicate="#{getObject('shibboleth.authn.Function.resultCachingPredicate')}"
- p:resultLookupStrategy="#{getObject('shibboleth.authn.Function.ResultLookupStrategy') ?: getObject('DefaultResultLookupStrategy')}" />
+ p:classifiedMessages="#{getObject('shibboleth.authn.Function.ClassifiedMessageMap')}"
+ p:resultLookupStrategy="#{getObject('shibboleth.authn.Function.ResultLookupStrategy') ?: getObject('DefaultResultLookupStrategy')}"
+ p:populateAuditContextAction="#{%{idp.authn.Function.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('shibboleth.authn.Function.PopulateAuditContext') : null}"
+ p:writeAuditLogAction="#{%{idp.authn.Function.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('WriteAuditLog') : null}" />
<bean id="PopulateSubjectCanonicalizationContext"
class="net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext" scope="prototype"
p:availableFlows-ref="shibboleth.PostLoginSubjectCanonicalizationFlows" />
+ <!-- Audit logging beans. -->
+
+ <util:map id="shibboleth.authn.AuditFormattingMap">
+ <entry key="#{'%{idp.authn.Function.audit.category:Shibboleth-Audit.Function}'.trim()}"
+ value="#{'%{idp.authn.Function.audit.format:%a|%T|%SP|%s|%AF|%u|%AR|%UA}'.trim()}" />
+ </util:map>
+
+ <bean id="shibboleth.authn.Function.DefaultAuditExtractors" parent="shibboleth.authn.DefaultAuditExtractors" lazy-init="true"
+ class="org.springframework.beans.factory.config.MapFactoryBean">
+ <property name="sourceMap">
+ <map merge="true" />
+ </property>
+ </bean>
+
+ <bean id="shibboleth.authn.Function.PopulateAuditContext" parent="shibboleth.authn.AbstractPopulateAuditContext" lazy-init="true"
+ p:fieldExtractors="#{getObject('shibboleth.authn.Function.AuditExtractors') ?: getObject('shibboleth.authn.Function.DefaultAuditExtractors')}"
+ p:clearAuditContext="true" />
+
</beans>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/ipaddress-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/ipaddress-authn-beans.xml
index 3c2d22801..3be40a959 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/ipaddress-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/ipaddress-authn-beans.xml
@@ -18,25 +18,6 @@
<bean class="net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor" />
<bean class="net.shibboleth.idp.profile.impl.ProfileActionBeanPostProcessor" />
- <!-- Default message map. -->
- <util:map id="shibboleth.authn.IPAddress.ClassifiedMessageMap">
- <entry key="RequestUnsupported">
- <list>
- <value>RequestUnsupported</value>
- </list>
- </entry>
- <entry key="NoCredentials">
- <list>
- <value>NoCredentials</value>
- </list>
- </entry>
- <entry key="InvalidCredentials">
- <list>
- <value>InvalidCredentials</value>
- </list>
- </entry>
- </util:map>
-
<import resource="conditional:%{idp.home}/conf/authn/ipaddress-authn-config.xml" />
<bean id="ExtractUserAgentAddress" class="net.shibboleth.idp.authn.impl.ExtractUserAgentAddress" scope="prototype"
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-beans.xml
index 8831d5a80..fadcda3e5 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-beans.xml
@@ -43,15 +43,6 @@
<bean id="shibboleth.authn.JAAS.LoginConfigNames" parent="shibboleth.CommaDelimStringArray"
c:_0="#{'%{idp.authn.JAAS.loginConfigNames:ShibUserPassAuth}'.trim()}" />
- <!-- Default message map. -->
- <util:map id="shibboleth.authn.Password.ClassifiedMessageMap">
- <entry key="RequestUnsupported">
- <list>
- <value>RequestUnsupported</value>
- </list>
- </entry>
- </util:map>
-
<import resource="conditional:%{idp.home}/conf/authn/password-authn-config.xml" />
<bean id="ExtractUsernamePasswordFromBasicAuth"
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-authn-beans.xml
index 954cbe1ab..0364ca2b3 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-authn-beans.xml
@@ -22,29 +22,8 @@
<bean id="shibboleth.authn.RemoteUser.externalAuthnPathStrategy" parent="shibboleth.Functions.Constant"
c:target="#{getObject('shibboleth.authn.RemoteUser.externalAuthnPath') ?: '%{idp.authn.RemoteUser.externalAuthnPath:contextRelative:/Authn/RemoteUser}'.trim()}" />
- <!-- Default message map. -->
- <util:map id="shibboleth.authn.RemoteUser.ClassifiedMessageMap">
- <entry key="RequestUnsupported">
- <list>
- <value>RequestUnsupported</value>
- </list>
- </entry>
- <entry key="NoCredentials">
- <list>
- <value>NoCredentials</value>
- </list>
- </entry>
- <entry key="InvalidCredentials">
- <list>
- <value>InvalidCredentials</value>
- </list>
- </entry>
- </util:map>
-
<import resource="conditional:%{idp.home}/conf/authn/remoteuser-authn-config.xml" />
- <bean id="DefaultCleanupHook" class="net.shibboleth.idp.authn.impl.ValidateExternalAuthentication.UsernameCleanupHook" />
-
<bean id="ValidateExternalAuthentication"
class="net.shibboleth.idp.authn.impl.ValidateExternalAuthentication" scope="prototype"
p:metricName="net.shibboleth.idp.authn.remoteuser"
@@ -52,7 +31,6 @@
p:addDefaultPrincipals="#{getObject('shibboleth.authn.RemoteUser.addDefaultPrincipals') ?: %{idp.authn.RemoteUser.addDefaultPrincipals:true}}"
p:classifiedMessages="#{getObject('shibboleth.authn.RemoteUser.ClassifiedMessageMap')}"
p:resultCachingPredicate="#{getObject('shibboleth.authn.RemoteUser.resultCachingPredicate')}"
- p:cleanupHook-ref="DefaultCleanupHook"
p:populateAuditContextAction="#{%{idp.authn.RemoteUser.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('shibboleth.authn.RemoteUser.PopulateAuditContext') : null}"
p:writeAuditLogAction="#{%{idp.authn.RemoteUser.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('WriteAuditLog') : null}" />
@@ -70,14 +48,7 @@
<bean id="shibboleth.authn.RemoteUser.DefaultAuditExtractors" parent="shibboleth.authn.DefaultAuditExtractors" lazy-init="true"
class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
- <map merge="true">
- <entry>
- <key>
- <util:constant static-field="net.shibboleth.idp.profile.IdPAuditFields.USERNAME"/>
- </key>
- <bean class="net.shibboleth.idp.authn.audit.impl.AttemptedUsernameAuditExtractor" />
- </entry>
- </map>
+ <map merge="true"/>
</property>
</bean>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-internal-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-internal-authn-beans.xml
index 46d50b790..2366e5dd8 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-internal-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-internal-authn-beans.xml
@@ -24,25 +24,6 @@
<bean id="shibboleth.authn.RemoteUser.checkAttributes" parent="shibboleth.CommaDelimStringArray"
c:_0="#{'%{idp.authn.RemoteUserInternal.checkAttributes:}'.trim()}" />
- <!-- Default message map. -->
- <util:map id="shibboleth.authn.RemoteUser.ClassifiedMessageMap">
- <entry key="RequestUnsupported">
- <list>
- <value>RequestUnsupported</value>
- </list>
- </entry>
- <entry key="NoCredentials">
- <list>
- <value>NoCredentials</value>
- </list>
- </entry>
- <entry key="InvalidCredentials">
- <list>
- <value>InvalidCredentials</value>
- </list>
- </entry>
- </util:map>
-
<import resource="conditional:%{idp.home}/conf/authn/remoteuser-internal-authn-config.xml" />
<bean class="net.shibboleth.ext.spring.util.DeprecatedBeanDetector" c:_1="remoteuser-internal-authn-config.xml">
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/spnego-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/spnego-authn-beans.xml
index dbddfac61..a123b4bfb 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/spnego-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/spnego-authn-beans.xml
@@ -47,19 +47,39 @@
<!-- Action beans. -->
<bean id="ValidateExternalAuthentication"
- class="net.shibboleth.idp.authn.impl.ValidateExternalAuthentication" scope="prototype"
- p:metricName="net.shibboleth.idp.authn.spnego"
- p:matchExpression="#{getObject('shibboleth.authn.SPNEGO.matchExpression') ?: '%{idp.authn.SPNEGO.matchExpression:}'}"
- p:addDefaultPrincipals="#{getObject('shibboleth.authn.SPNEGO.addDefaultPrincipals') ?: %{idp.authn.SPNEGO.addDefaultPrincipals:true}}"
- p:classifiedMessages="#{getObject('shibboleth.authn.SPNEGO.ClassifiedMessageMap')}" />
+ class="net.shibboleth.idp.authn.impl.ValidateExternalAuthentication" scope="prototype"
+ p:metricName="net.shibboleth.idp.authn.spnego"
+ p:matchExpression="#{getObject('shibboleth.authn.SPNEGO.matchExpression') ?: '%{idp.authn.SPNEGO.matchExpression:}'}"
+ p:addDefaultPrincipals="#{getObject('shibboleth.authn.SPNEGO.addDefaultPrincipals') ?: %{idp.authn.SPNEGO.addDefaultPrincipals:true}}"
+ p:classifiedMessages="#{getObject('shibboleth.authn.SPNEGO.ClassifiedMessageMap')}"
+ p:populateAuditContextAction="#{%{idp.authn.SPNEGO.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('shibboleth.authn.SPNEGO.PopulateAuditContext') : null}"
+ p:writeAuditLogAction="#{%{idp.authn.SPNEGO.audit.enabled:%{idp.authn.audit.enabled:false}} ? getObject('WriteAuditLog') : null}" />
<bean id="SPNEGOAutoLoginManager"
- class="net.shibboleth.idp.authn.spnego.impl.SPNEGOAutoLoginManager"
- p:cookieManager-ref="shibboleth.UserPrefsCookieManager"
- p:cookieName="%{idp.authn.SPNEGO.cookieName:_idp_spnego_autologin}" />
+ class="net.shibboleth.idp.authn.spnego.impl.SPNEGOAutoLoginManager"
+ p:cookieManager-ref="shibboleth.UserPrefsCookieManager"
+ p:cookieName="%{idp.authn.SPNEGO.cookieName:_idp_spnego_autologin}" />
<bean id="PopulateSubjectCanonicalizationContext"
class="net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext" scope="prototype"
p:availableFlows-ref="shibboleth.PostLoginSubjectCanonicalizationFlows" />
+ <!-- Audit logging beans. -->
+
+ <util:map id="shibboleth.authn.AuditFormattingMap">
+ <entry key="#{'%{idp.authn.SPNEGO.audit.category:Shibboleth-Audit.SPNEGO}'.trim()}"
+ value="#{'%{idp.authn.SPNEGO.audit.format:%a|%T|%SP|%s|%AF|%u|%AR|%UA}'.trim()}" />
+ </util:map>
+
+ <bean id="shibboleth.authn.SPNEGO.DefaultAuditExtractors" parent="shibboleth.authn.DefaultAuditExtractors" lazy-init="true"
+ class="org.springframework.beans.factory.config.MapFactoryBean">
+ <property name="sourceMap">
+ <map merge="true" />
+ </property>
+ </bean>
+
+ <bean id="shibboleth.authn.SPNEGO.PopulateAuditContext" parent="shibboleth.authn.AbstractPopulateAuditContext" lazy-init="true"
+ p:fieldExtractors="#{getObject('shibboleth.authn.SPNEGO.AuditExtractors') ?: getObject('shibboleth.authn.SPNEGO.DefaultAuditExtractors')}"
+ p:clearAuditContext="true" />
+
</beans>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/x509-internal-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/x509-internal-authn-beans.xml
index 0250a7a0e..97212f2ea 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/x509-internal-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/x509-internal-authn-beans.xml
@@ -18,20 +18,6 @@
<bean class="net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor" />
<bean class="net.shibboleth.idp.profile.impl.ProfileActionBeanPostProcessor" />
- <!-- Default message map. -->
- <util:map id="shibboleth.authn.X509Internal.ClassifiedMessageMap">
- <entry key="RequestUnsupported">
- <list>
- <value>RequestUnsupported</value>
- </list>
- </entry>
- <entry key="InvalidCredentials">
- <list>
- <value>InvalidCredentials</value>
- </list>
- </entry>
- </util:map>
-
<import resource="conditional:%{idp.home}/conf/authn/x509-internal-authn-config.xml" />
<bean id="ExtractX509CertificateFromRequest"
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/external-authn-config.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/external-authn-config.xml
index 0d19b78d9..ceb92663d 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/external-authn-config.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/external-authn-config.xml
@@ -25,32 +25,17 @@
kinds of errors for use in your templates and as events in flows.
Keys are events to signal, values are error codes.
-
- The examples here just allow external signaling of the exact type of condition to record.
If you want to "fall-through" to other login flows, include a mapping to "ReselectFlow".
-->
+ <!--
<util:map id="shibboleth.authn.External.ClassifiedMessageMap">
- <entry key="UnknownUsername">
+ <entry key="ReselectFlow">
<list>
<value>UnknownUsername</value>
</list>
</entry>
- <entry key="InvalidPassword">
- <list>
- <value>InvalidPassword</value>
- </list>
- </entry>
- <entry key="ExpiredPassword">
- <list>
- <value>ExpiredPassword</value>
- </list>
- </entry>
- <entry key="ExpiringPassword">
- <list>
- <value>ExpiringPassword</value>
- </list>
- </entry>
</util:map>
+ -->
</beans>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/function-authn-config.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/function-authn-config.xml
index 180555631..636fec5f0 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/function-authn-config.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/function-authn-config.xml
@@ -15,6 +15,9 @@
<!--
The entire flow depends on the execution of a function bean you supply. A pathological script example
is below. The function may return a String, Principal, Subject, or a null to signal failure.
+
+ You may also raise an exception and install a bean named shibboleth.authn.Function.ClassifiedMessageMap
+ to map exception messages to events.
-->
<bean id="shibboleth.authn.Function.ResultLookupStrategy"
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/spnego-authn-config.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/spnego-authn-config.xml
index 5be020400..b26c020c7 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/spnego-authn-config.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/spnego-authn-config.xml
@@ -31,24 +31,4 @@
</util:list>
- <!--
- Define entries here to map events or error messages returned by the SPNEGO module
- and classify them as particular kinds of errors for use in your templates and as
- events in flows.
-
- Keys are events to signal, values are error codes.
- -->
- <util:map id="shibboleth.authn.SPNEGO.ClassifiedMessageMap">
- <entry key="SPNEGONotAvailable">
- <list>
- <value>SPNEGONotAvailable</value>
- </list>
- </entry>
- <entry key="NTLMUnsupported">
- <list>
- <value>NTLMUnsupported</value>
- </list>
- </entry>
- </util:map>
-
</beans>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list