[java-identity-provider] branch main updated: IDP-2126 - Admin flow to report on config settings
Scott Cantor
cantor.2 at osu.edu
Mon Jun 12 16:20: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=6ec010d19f1689141b89a30c0735a3dbd52606c0
The following commit(s) were added to refs/heads/main by this push:
new 6ec010d19 IDP-2126 - Admin flow to report on config settings
6ec010d19 is described below
commit 6ec010d19f1689141b89a30c0735a3dbd52606c0
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Jun 12 12:19:36 2023 -0400
IDP-2126 - Admin flow to report on config settings
https://shibboleth.atlassian.net/browse/IDP-2126
---
idp-admin-impl/pom.xml | 9 +
.../idp/admin/impl/DumpConfigRequest.java | 99 +++++++
.../idp/admin/impl/DumpConfigRequestDecoder.java | 159 ++++++++++++
.../shibboleth/idp/admin/impl/OutputConfig.java | 284 +++++++++++++++++++++
.../shibboleth/idp/admin/impl/OutputMetrics.java | 9 +-
.../config/AuthenticationProfileConfiguration.java | 7 +
.../cas/config/AbstractProtocolConfiguration.java | 2 +
.../idp/cas/config/LoginConfiguration.java | 2 +
.../idp/cas/config/ValidateConfiguration.java | 4 +
.../net/shibboleth/idp/conf/admin-system.xml | 17 ++
.../net/shibboleth/idp/conf/webflow-config.xml | 1 +
.../idp/flows/admin/dumpconfig-beans.xml | 96 +++++++
.../shibboleth/idp/flows/admin/dumpconfig-flow.xml | 65 +++++
.../idp/module/conf/admin/admin.properties | 8 +
.../InterceptorAwareProfileConfiguration.java | 3 +
.../config/BrowserSSOProfileConfiguration.java | 11 +-
.../profile/config/ECPProfileConfiguration.java | 2 +
.../impl/SingleLogoutProfileConfiguration.java | 3 +-
18 files changed, 773 insertions(+), 8 deletions(-)
diff --git a/idp-admin-impl/pom.xml b/idp-admin-impl/pom.xml
index 607ce0352..8401a0d9c 100644
--- a/idp-admin-impl/pom.xml
+++ b/idp-admin-impl/pom.xml
@@ -27,6 +27,11 @@
<artifactId>idp-admin-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>idp-cas-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>idp-core</artifactId>
@@ -48,6 +53,10 @@
<artifactId>shib-profile-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-messaging-api</artifactId>
+ </dependency>
<dependency>
<groupId>${opensaml.groupId}</groupId>
<artifactId>opensaml-profile-api</artifactId>
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DumpConfigRequest.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DumpConfigRequest.java
new file mode 100644
index 000000000..85c1b3c2c
--- /dev/null
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DumpConfigRequest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.admin.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.StringSupport;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Object representing a request to mock a profile request to obtain the effective configuration.
+ *
+ * @since 5.0.0
+ */
+ at ThreadSafe
+public class DumpConfigRequest {
+
+ /** Profile identifier to simulate a response for. */
+ @Nonnull @NotEmpty private final String profileId;
+
+ /** Protocol identifier for metadata access. */
+ @Nonnull @NotEmpty private final String protocolId;
+
+ /** The ID of the requester. */
+ @Nonnull @NotEmpty private final String requesterId;
+
+ /**
+ * Constructor.
+ *
+ * @param profile profile ID
+ * @param protocol protocol ID for metadata access
+ * @param requester ID of requester
+ */
+ public DumpConfigRequest(@Nonnull final String profile, @Nonnull final String protocol,
+ @Nonnull final String requester) {
+
+ profileId = Constraint.isNotNull(StringSupport.trimOrNull(profile), "Profile ID cannot be null or empty");
+ protocolId = Constraint.isNotNull(StringSupport.trimOrNull(protocol), "Protocol cannot be null or empty");
+ requesterId = Constraint.isNotNull(StringSupport.trimOrNull(requester),
+ "Requester name cannot be null or empty");
+ }
+
+ /**
+ * Get the profile to simulate.
+ *
+ * @return profile ID to simulate
+ */
+ @Nonnull @NotEmpty public String getProfileId() {
+ return profileId;
+ }
+
+ /**
+ * Get the protocol for metadata access.
+ *
+ * @return protocol for metadata access
+ */
+ @Nonnull @NotEmpty public String getProtocolId() {
+ return protocolId;
+ }
+
+ /**
+ * Get the ID of the requesting relying party.
+ *
+ * @return ID of the requesting relying party
+ */
+ @Nonnull @NotEmpty public String getRequesterId() {
+ return requesterId;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("profileId", profileId)
+ .add("protocolId", protocolId)
+ .add("requesterId", requesterId)
+ .toString();
+ }
+
+}
\ No newline at end of file
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DumpConfigRequestDecoder.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DumpConfigRequestDecoder.java
new file mode 100644
index 000000000..e980b17bd
--- /dev/null
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DumpConfigRequestDecoder.java
@@ -0,0 +1,159 @@
+/*
+ * 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.admin.impl;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.opensaml.messaging.decoder.servlet.AbstractHttpServletRequestMessageDecoder;
+import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
+import org.opensaml.saml.common.messaging.context.SAMLProtocolContext;
+import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+
+import jakarta.servlet.http.HttpServletRequest;
+import net.shibboleth.idp.cas.config.AbstractProtocolConfiguration;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.primitive.StringSupport;
+
+/**
+ * Decodes an incoming configuration reporting message.
+ */
+public class DumpConfigRequestDecoder extends AbstractHttpServletRequestMessageDecoder {
+
+ /** Name of the query parameter carrying the profile: {@value} . */
+ @Nonnull @NotEmpty public static final String PROFILE_PARAM = "profile";
+
+ /** Name of the query parameter carrying the protocol: {@value} . */
+ @Nonnull @NotEmpty public static final String PROTOCOL_PARAM = "protocol";
+
+ /** Name of the query parameter for the SAML 1 protocol: {@value} . */
+ @Nonnull @NotEmpty public static final String SAML1_PARAM = "saml1";
+
+ /** Name of the query parameter for the SAML 2 protocol: {@value} . */
+ @Nonnull @NotEmpty public static final String SAML2_PARAM = "saml2";
+
+ /** Name of the query parameter for the CAS protocol: {@value} . */
+ @Nonnull @NotEmpty public static final String CAS_PARAM = "cas";
+
+ /** Name of the query parameter for the OIDC protocol: {@value} . */
+ @Nonnull @NotEmpty public static final String OIDC_PARAM = "oidc";
+
+ /** Name of the query parameter carrying the requester: {@value} . */
+ @Nonnull @NotEmpty public static final String REQUESTER_ID_PARAM = "requester";
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doDecode() throws MessageDecodingException {
+ final HttpServletRequest request = getHttpServletRequest();
+ if (request == null) {
+ throw new MessageDecodingException("Unable to locate HttpServletRequest");
+ }
+
+ final String profile = getProfileId(request);
+ final DumpConfigRequest message = new DumpConfigRequest(profile, getProtocolId(request),
+ getRequesterId(request));
+ final MessageContext messageContext = new MessageContext();
+ messageContext.setMessage(message);
+ setMessageContext(messageContext);
+
+ final SAMLPeerEntityContext peerCtx = new SAMLPeerEntityContext();
+ // TODO: allow for IdP role...
+ peerCtx.setRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+ peerCtx.setEntityId(message.getRequesterId());
+ messageContext.addSubcontext(peerCtx, true);
+
+ messageContext.ensureSubcontext(SAMLProtocolContext.class).setProtocol(message.getProtocolId());
+ }
+
+ /**
+ * Get the profile ID.
+ *
+ * @param request current HTTP request
+ *
+ * @return the profile ID
+ *
+ * @throws MessageDecodingException thrown if the request does not contain a profile ID
+ */
+ @Nonnull @NotEmpty protected String getProfileId(@Nonnull final HttpServletRequest request)
+ throws MessageDecodingException {
+ final String id = StringSupport.trimOrNull(request.getParameter(PROFILE_PARAM));
+ if (id == null) {
+ throw new MessageDecodingException("Request did not contain the " + PROFILE_PARAM + " query parameter.");
+ }
+
+ if (id.startsWith("http")) {
+ return id;
+ } else if (id.startsWith("/")) {
+ return "http://shibboleth.net/ns/profiles" + id;
+ } else {
+ return "http://shibboleth.net/ns/profiles/" + id;
+ }
+ }
+
+ /**
+ * Get the ID of the requester.
+ *
+ * @param request current HTTP request
+ *
+ * @return the ID of the requester
+ *
+ * @throws MessageDecodingException thrown if the request does not contain a requester name
+ */
+ @Nonnull @NotEmpty protected String getRequesterId(@Nonnull final HttpServletRequest request)
+ throws MessageDecodingException {
+ final String name = StringSupport.trimOrNull(request.getParameter(REQUESTER_ID_PARAM));
+ if (name == null) {
+ throw new MessageDecodingException("Request did not contain the " + REQUESTER_ID_PARAM
+ + " query parameter.");
+ }
+ return name;
+ }
+
+ /**
+ * Get the protocol string used for metadata access.
+ *
+ * @param request current HTTP request
+ *
+ * @return the protocol
+ *
+ * @throws MessageDecodingException if unable to determine the protocol
+ */
+ @Nonnull @NotEmpty protected String getProtocolId(@Nonnull final HttpServletRequest request)
+ throws MessageDecodingException {
+ final String protocol = StringSupport.trimOrNull(request.getParameter(PROTOCOL_PARAM));
+ if (protocol != null) {
+ return protocol;
+ }
+
+ if (request.getParameter(SAML1_PARAM) != null) {
+ return SAMLConstants.SAML11P_NS;
+ } else if (request.getParameter(SAML2_PARAM) != null) {
+ return SAMLConstants.SAML20P_NS;
+ } else if (request.getParameter(CAS_PARAM) != null) {
+ return AbstractProtocolConfiguration.PROTOCOL_URI;
+ } else if (request.getParameter(OIDC_PARAM) != null) {
+ return "http://openid.net/specs/openid-connect-core-1_0.html";
+ }
+
+ throw new MessageDecodingException("Request did not contain the " + PROTOCOL_PARAM
+ + " query parameter.");
+ }
+
+}
\ No newline at end of file
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputConfig.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputConfig.java
new file mode 100644
index 000000000..13ce3455d
--- /dev/null
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputConfig.java
@@ -0,0 +1,284 @@
+/*
+ * 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.admin.impl;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Map;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+import org.springframework.core.annotation.AnnotationUtils;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.idp.profile.IdPEventIds;
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.NullableElements;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.component.IdentifiableComponent;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
+
+import jakarta.servlet.http.HttpServletResponse;
+
+/**
+ * Action that outputs the settings from the effective {@link ProfileConfiguration} and so on.
+ *
+ * <p>On success, a 200 HTTP status is returned. On failure, a non-successful HTTP status is returned.</p>
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_PROFILE_CTX}
+ * @event {@link IdPEventIds#INVALID_RELYING_PARTY_CTX}
+ * @event {@link IdPEventIds#INVALID_RELYING_PARTY_CONFIG}
+ * @event {@link IdPEventIds#INVALID_PROFILE_CONFIG}
+ * @event {@link EventIds#IO_ERROR}
+ *
+ * @since 5.0.0
+ */
+public class OutputConfig extends AbstractProfileAction {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(OutputConfig.class);
+
+ /** Value for Access-Control-Allow-Origin header, if any. */
+ @Nullable private String allowedOrigin;
+
+ /** Name of JSONP callback function, if any. */
+ @Nullable private String jsonpCallbackName;
+
+ /** Lookup strategy for {@link RelyingPartyContext}. */
+ @Nonnull private Function<ProfileRequestContext,RelyingPartyContext> relyingPartyContextLookupStrategy;
+
+ /** Relying party context. */
+ @NonnullBeforeExec private RelyingPartyContext relyingPartyContext;
+
+ /** Constructor. */
+ public OutputConfig() {
+ relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
+ }
+
+ /**
+ * Set the value of the Access-Control-Allow-Origin CORS header, if any.
+ *
+ * @param origin header value
+ */
+ public void setAllowedOrigin(@Nullable final String origin) {
+ checkSetterPreconditions();
+
+ allowedOrigin = StringSupport.trimOrNull(origin);
+ }
+
+ /**
+ * Set a JSONP callback function to wrap the result in, if any.
+ *
+ * @param callbackName callback function name.
+ */
+ public void setJSONPCallbackName(@Nullable final String callbackName) {
+ checkSetterPreconditions();
+
+ jsonpCallbackName = StringSupport.trimOrNull(callbackName);
+ }
+
+ /**
+ * Set the lookup strategy to locate the {@link RelyingPartyContext}.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setRelyingPartyContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,RelyingPartyContext> strategy) {
+ checkSetterPreconditions();
+
+ relyingPartyContextLookupStrategy = Constraint.isNotNull(strategy,
+ "RelyingPartyContext lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ relyingPartyContext = relyingPartyContextLookupStrategy.apply(profileRequestContext);
+ if (relyingPartyContext == null) {
+ log.warn("{} No RelyingPartyContext available", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_RELYING_PARTY_CTX);
+ return false;
+ } else if (relyingPartyContext.getConfiguration() == null) {
+ log.warn("{} No RelyingPartyConfiguration available", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_RELYING_PARTY_CONFIG);
+ return false;
+ } else if (relyingPartyContext.getProfileConfig() == null) {
+ log.warn("{} No ProfileConfiguration available", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return false;
+ }
+
+ final HttpServletResponse response = getHttpServletResponse();
+ if (response == null) {
+ log.warn("{} No HttpServletResponse available", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ try {
+ final HttpServletResponse response = getHttpServletResponse();
+ assert response != null;
+ response.setHeader("Cache-Control", "must-revalidate,no-cache,no-store");
+ response.setStatus(HttpServletResponse.SC_OK);
+ if (allowedOrigin != null) {
+ response.setHeader("Access-Control-Allow-Origin", allowedOrigin);
+ }
+
+ final ObjectMapper mapper = new ObjectMapper();
+
+ mapper.registerModule(new JavaTimeModule());
+ // These don't do much of anything, except the first one I think.
+ mapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
+ mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
+
+ if (jsonpCallbackName != null) {
+ response.setContentType("application/javascript");
+ mapper.writer().writeValue(response.getOutputStream(), getConfig(profileRequestContext));
+ } else {
+ response.setContentType("application/json");
+ mapper.writer().writeValue(response.getOutputStream(), getConfig(profileRequestContext));
+ }
+ } catch (final IOException e) {
+ log.error("{} I/O error responding to request", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
+ }
+ }
+
+ /**
+ * Extract configuration settings into a map to output.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return configuration settings map
+ */
+ @Nonnull @NullableElements private Map<String,Object> getConfig(
+ @Nonnull final ProfileRequestContext profileRequestContext) {
+
+ final Map<String,Object> settings = new HashMap<>();
+
+ settings.put("RelyingPartyConfiguration",
+ getSettings(profileRequestContext, relyingPartyContext.ensureConfiguration()));
+
+ settings.put("ProfileConfiguration",
+ getSettings(profileRequestContext, relyingPartyContext.ensureProfileConfig()));
+
+ return settings;
+ }
+
+ /**
+ * Interrogate a target object for configuration settings, extract them, and return in a map.
+ *
+ * @param profileRequestContext profile request context
+ * @param target target object
+ *
+ * @return map of settings
+ */
+// Checkstyle: CyclomaticComplexity OFF
+ @Nonnull @NullableElements @Unmodifiable @NotLive
+ private Map<String,Object> getSettings(@Nonnull final ProfileRequestContext profileRequestContext,
+ @Nonnull final Object target) {
+ final Map<String,Object> settings = new HashMap<>();
+
+ // Specially handle ID property.
+ if (target instanceof IdentifiableComponent comp) {
+ settings.put("id", comp.getId());
+ }
+
+ final Method[] methods = target.getClass().getMethods();
+ for (final Method m : methods) {
+ assert m != null;
+ // The Spring method deals with the lack of inheritance on method-level annotations.
+ final ConfigurationSetting annotation = AnnotationUtils.findAnnotation(m, ConfigurationSetting.class);
+ if (annotation == null || annotation.name() == null || annotation.name().isEmpty()) {
+ continue;
+ }
+ final Class<?>[] paramTypes = m.getParameterTypes();
+ if (paramTypes.length == 1 && paramTypes[0].isAssignableFrom(ProfileRequestContext.class)) {
+ try {
+ final Object ret = m.invoke(target, profileRequestContext);
+ if (ret == null) {
+ continue;
+ }
+ if (ret instanceof IdentifiableComponent comp) {
+ settings.put(annotation.name(), comp.getId());
+ } else if (ret instanceof Collection<?> c) {
+ if (!c.isEmpty()) {
+ settings.put(annotation.name(), ret);
+ }
+ } else if (isPrimitive(ret)) {
+ settings.put(annotation.name(), ret);
+ } else {
+ settings.put(annotation.name(), ret.getClass().getName());
+ }
+ } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ log.error("{} Error introspecting configuration setting '{}'", getLogPrefix(), annotation.name(),
+ e);
+ }
+ }
+ }
+
+ return settings;
+ }
+// Checkstyle: CyclomaticComplexity ON
+
+ private boolean isPrimitive(@Nullable final Object o) {
+ return o instanceof Boolean
+ || o instanceof Integer
+ || o instanceof Long
+ || o instanceof Double
+ || o instanceof String
+ || o instanceof Duration
+ || o instanceof Instant;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
index e6e588a32..01a9e4bdc 100644
--- a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
@@ -224,14 +224,10 @@ public class OutputMetrics extends AbstractProfileAction {
/** {@inheritDoc} */
@Override
- protected boolean doPreExecute(final @Nonnull ProfileRequestContext profileRequestContext) {
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
if (!super.doPreExecute(profileRequestContext)) {
return false;
- } else if (getHttpServletResponse() == null) {
- log.debug("{} No HttpServletResponse available", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
- return false;
}
final SpringRequestContext springRequestContext =
@@ -248,6 +244,7 @@ public class OutputMetrics extends AbstractProfileAction {
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
return false;
}
+
final HttpServletResponse response = getHttpServletResponse();
if (response == null) {
log.warn("{} No HttpServletResponse available", getLogPrefix());
@@ -270,7 +267,7 @@ public class OutputMetrics extends AbstractProfileAction {
}
/** {@inheritDoc} */
- @Override protected void doExecute(final @Nonnull ProfileRequestContext profileRequestContext) {
+ @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
MetricFilter filter = ALL_METRICS.equals(metricId) ? MetricFilter.ALL : metricFilterMap.get(metricId);
if (filter == null) {
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/AuthenticationProfileConfiguration.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/AuthenticationProfileConfiguration.java
index c4c52a754..af4136a26 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/AuthenticationProfileConfiguration.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/AuthenticationProfileConfiguration.java
@@ -27,6 +27,7 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NonNegative;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
import net.shibboleth.shared.annotation.constraint.NotLive;
@@ -42,6 +43,7 @@ public interface AuthenticationProfileConfiguration extends ProfileConfiguration
*
* @return default authentication methods to use
*/
+ @ConfigurationSetting(name="defaultAuthenticationMethods")
@Nonnull @NonnullElements @NotLive @Unmodifiable List<Principal> getDefaultAuthenticationMethods(
@Nullable final ProfileRequestContext profileRequestContext);
@@ -56,6 +58,7 @@ public interface AuthenticationProfileConfiguration extends ProfileConfiguration
*
* @return a set of authentication flow IDs to allow
*/
+ @ConfigurationSetting(name="authenticationFlows")
@Nonnull @NonnullElements @NotLive @Unmodifiable Set<String> getAuthenticationFlows(
@Nullable final ProfileRequestContext profileRequestContext);
@@ -70,6 +73,7 @@ public interface AuthenticationProfileConfiguration extends ProfileConfiguration
*
* @return a set of interceptor flow IDs to enable
*/
+ @ConfigurationSetting(name="postAuthenticationFlows")
@Nonnull @NonnullElements @NotLive @Unmodifiable List<String> getPostAuthenticationFlows(
@Nullable final ProfileRequestContext profileRequestContext);
@@ -82,6 +86,7 @@ public interface AuthenticationProfileConfiguration extends ProfileConfiguration
*
* @since 4.0.0
*/
+ @ConfigurationSetting(name="forceAuthn")
boolean isForceAuthn(@Nullable final ProfileRequestContext profileRequestContext);
/**
@@ -95,6 +100,7 @@ public interface AuthenticationProfileConfiguration extends ProfileConfiguration
*
* @since 4.0.0
*/
+ @ConfigurationSetting(name="proxyCount")
@NonNegative @Nullable Integer getProxyCount(@Nullable final ProfileRequestContext profileRequestContext);
/**
@@ -108,4 +114,5 @@ public interface AuthenticationProfileConfiguration extends ProfileConfiguration
default boolean isLocal() {
return false;
}
+
}
\ No newline at end of file
diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/AbstractProtocolConfiguration.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/AbstractProtocolConfiguration.java
index 2b38ae23f..2441319eb 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/AbstractProtocolConfiguration.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/AbstractProtocolConfiguration.java
@@ -31,6 +31,7 @@ import org.opensaml.security.config.SecurityConfiguration;
import net.shibboleth.idp.cas.ticket.TicketIdentifierGenerationStrategy;
import net.shibboleth.idp.profile.config.AbstractInterceptorAwareProfileConfiguration;
import net.shibboleth.profile.config.AttributeResolvingProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.component.InitializableComponent;
import net.shibboleth.shared.logic.Constraint;
@@ -95,6 +96,7 @@ public abstract class AbstractProtocolConfiguration extends AbstractInterceptorA
*
* @return ticket validity period
*/
+ @ConfigurationSetting(name="ticketValidityPeriod")
@Nonnull public Duration getTicketValidityPeriod(@Nullable final ProfileRequestContext profileRequestContext) {
final Duration ticketTTL = ticketValidityPeriodLookupStrategy.apply(profileRequestContext);
diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
index 27d9f4361..ccbbddd0a 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
@@ -31,6 +31,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
import net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NonNegative;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -230,6 +231,7 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
*
* @since 4.2.0
*/
+ @ConfigurationSetting(name="storeConsentInTickets")
public boolean isStoreConsentInTickets(@Nullable final ProfileRequestContext profileRequestContext) {
return storeConsentInTicketsPredicate.test(profileRequestContext);
}
diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/ValidateConfiguration.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/ValidateConfiguration.java
index 45c636398..b6abbedd2 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/ValidateConfiguration.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/ValidateConfiguration.java
@@ -28,6 +28,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.idp.cas.service.DefaultServiceComparator;
import net.shibboleth.idp.cas.ticket.TicketIdentifierGenerationStrategy;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.FunctionSupport;
@@ -95,6 +96,7 @@ public class ValidateConfiguration extends AbstractProtocolConfiguration {
*
* @return PGTIOU ticket ID generator
*/
+ @ConfigurationSetting(name="pGTIOUGenerator")
@Nonnull public IdentifierGenerationStrategy getPGTIOUGenerator(
@Nullable final ProfileRequestContext profileRequestContext) {
@@ -131,6 +133,7 @@ public class ValidateConfiguration extends AbstractProtocolConfiguration {
*
* @return ticket requester/validator comparator
*/
+ @ConfigurationSetting(name="serviceComparator")
@Nonnull public Comparator<String> getServiceComparator(
@Nullable final ProfileRequestContext profileRequestContext) {
return Constraint.isNotNull(
@@ -167,6 +170,7 @@ public class ValidateConfiguration extends AbstractProtocolConfiguration {
*
* @return attribute name
*/
+ @ConfigurationSetting(name="userAttribute")
@Nullable public String getUserAttribute(@Nullable final ProfileRequestContext profileRequestContext) {
return userAttributeLookupStrategy.apply(profileRequestContext);
}
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
index e6342106b..9144a917a 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
@@ -92,6 +92,23 @@
</property>
</bean>
+ <bean parent="shibboleth.AdminFlow"
+ c:id="http://shibboleth.net/ns/profiles/dumpconfig"
+ p:loggingId="%{idp.dumpconfig.logging:DumpConfig}"
+ p:policyName="%{idp.dumpconfig.accessPolicy:AccessByIPAddress}"
+ p:nonBrowserSupported="%{idp.dumpconfig.nonBrowserSupported:false}"
+ p:authenticated="%{idp.dumpconfig.authenticated:false}"
+ p:resolveAttributes="%{idp.dumpconfig.resolveAttributes:false}">
+ <property name="postAuthenticationFlows">
+ <bean parent="shibboleth.CommaDelimStringArray"
+ c:_0="#{'%{idp.dumpconfig.postAuthenticationFlows:}'.trim()}" />
+ </property>
+ <property name="defaultAuthenticationMethodsByString">
+ <bean parent="shibboleth.CommaDelimStringArray"
+ c:_0="#{'%{idp.dumpconfig.defaultAuthenticationMethods:}'.trim()}" />
+ </property>
+ </bean>
+
<bean parent="shibboleth.AdminFlow"
c:id="http://shibboleth.net/ns/profiles/mdquery"
p:loggingId="%{idp.mdquery.logging:MetadataQuery}"
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/webflow-config.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/webflow-config.xml
index a5831dcbb..118511500 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/webflow-config.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/webflow-config.xml
@@ -25,6 +25,7 @@
<!-- Administrative and debugging flows. -->
<entry key="admin/hello" value="classpath:/net/shibboleth/idp/flows/admin/hello-flow.xml" />
<entry key="admin/resolvertest" value="classpath:/net/shibboleth/idp/flows/admin/resolvertest-flow.xml" />
+ <entry key="admin/dumpconfig" value="classpath:/net/shibboleth/idp/flows/admin/dumpconfig-flow.xml" />
<entry key="admin/reload-service" value="classpath:/net/shibboleth/idp/flows/admin/reload-service-flow.xml" />
<entry key="admin/reload-metadata" value="classpath:/net/shibboleth/idp/flows/admin/reload-metadata-flow.xml" />
<entry key="admin/lockout" value="classpath:/net/shibboleth/idp/flows/admin/lockout-flow.xml" />
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/dumpconfig-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/dumpconfig-beans.xml
new file mode 100644
index 000000000..b9450806b
--- /dev/null
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/dumpconfig-beans.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans
+ xmlns="http://www.springframework.org/schema/beans"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"
+ p:placeholderPrefix="%{" p:placeholderSuffix="}" />
+
+ <!-- Profile ID for flow. -->
+ <bean id="shibboleth.AdminProfileId" class="java.lang.String"
+ c:_0="http://shibboleth.net/ns/profiles/dumpconfig" />
+
+ <!-- Profile counter name. -->
+ <bean id="shibboleth.metrics.ProfileCounter" class="java.lang.String" c:_0="net.shibboleth.idp.profiles.dumpconfig" />
+
+ <!-- Default operation/resource suppliers for access checks. -->
+
+ <bean id="shibboleth.AdminOperationLookupStrategy" parent="shibboleth.Functions.Constant" c:target="read" />
+
+ <bean id="shibboleth.AdminResourceLookupStrategy" parent="shibboleth.Functions.Constant" c:target="dumpconfig" />
+
+ <bean id="DecodeMessage" class="org.opensaml.profile.action.impl.DecodeMessage" scope="prototype">
+ <constructor-arg>
+ <bean class="%{idp.dumpconfig.decoderClass:net.shibboleth.idp.admin.impl.DumpConfigRequestDecoder}" scope="prototype"
+ p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="PostDecodePopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext">
+ <property name="fieldExtractors">
+ <map>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.idp.saml.profile.SAMLAuditFields.PROTOCOL"/>
+ </key>
+ <bean parent="shibboleth.Functions.Compose">
+ <constructor-arg name="g">
+ <bean parent="shibboleth.Functions.Compose">
+ <constructor-arg name="g">
+ <bean class="org.opensaml.saml.common.messaging.context.navigate.SAMLProtocolContextProtocolFunction" />
+ </constructor-arg>
+ <constructor-arg name="f">
+ <ref bean="shibboleth.ChildLookup.SAMLProtocolContext" />
+ </constructor-arg>
+ </bean>
+ </constructor-arg>
+ <constructor-arg name="f">
+ <ref bean="shibboleth.MessageContextLookup.Inbound" />
+ </constructor-arg>
+ </bean>
+ </entry>
+ </map>
+ </property>
+ </bean>
+
+ <bean id="SAMLMetadataLookup"
+ class="net.shibboleth.idp.profile.impl.WebFlowMessageHandlerAdaptor" scope="prototype"
+ c:executionDirection="INBOUND">
+ <constructor-arg name="messageHandler">
+ <bean class="org.opensaml.saml.common.binding.impl.SAMLMetadataLookupHandler" scope="prototype">
+ <property name="roleDescriptorResolver">
+ <bean class="org.opensaml.saml.metadata.resolver.impl.PredicateRoleDescriptorResolver"
+ c:mdResolver-ref="shibboleth.MetadataResolver" />
+ </property>
+ </bean>
+ </constructor-arg>
+ </bean>
+
+ <bean id="InitializeRelyingPartyContexFromSAMLPeer"
+ class="net.shibboleth.idp.saml.profile.impl.InitializeRelyingPartyContextFromSAMLPeer" scope="prototype" />
+
+ <bean id="SelectRelyingPartyConfiguration"
+ class="net.shibboleth.idp.profile.impl.SelectRelyingPartyConfiguration" scope="prototype"
+ p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyResolverService" />
+
+ <bean id="SelectProfileConfiguration"
+ class="net.shibboleth.idp.profile.impl.SelectProfileConfiguration" scope="prototype" />
+
+ <bean id="PostLookupPopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
+ p:fieldExtractors="#{getObject('shibboleth.PostLookupAuditExtractors') ?: getObject('shibboleth.DefaultPostLookupAuditExtractors')}" />
+
+ <bean id="OutputConfig" class="net.shibboleth.idp.admin.impl.OutputConfig" scope="prototype"
+ p:httpServletResponseSupplier-ref="shibboleth.HttpServletResponseSupplier" />
+
+ <bean id="RecordResponseComplete" class="net.shibboleth.idp.profile.impl.RecordResponseComplete" scope="prototype" />
+
+</beans>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/dumpconfig-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/dumpconfig-flow.xml
new file mode 100644
index 000000000..386656705
--- /dev/null
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/admin/dumpconfig-flow.xml
@@ -0,0 +1,65 @@
+<flow xmlns="http://www.springframework.org/schema/webflow"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
+ parent="admin.abstract">
+
+ <!-- Start action. -->
+
+ <action-state id="InitializeProfileRequestContext">
+ <evaluate expression="InitializeProfileRequestContext" />
+ <evaluate expression="FlowStartPopulateAuditContext" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="DecodeMessage" />
+ </action-state>
+
+ <action-state id="DecodeMessage">
+ <evaluate expression="DecodeMessage" />
+ <evaluate expression="PostDecodePopulateAuditContext" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="DoAdminPreamble" />
+ </action-state>
+
+ <!-- Resume actual flow processing. -->
+
+ <action-state id="DoProfileWork">
+ <evaluate expression="CheckAccess" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="ContinueDecoding" />
+ </action-state>
+
+ <action-state id="ContinueDecoding">
+ <on-entry>
+ <!-- Clear any user authentication/attribute state. -->
+ <evaluate expression="opensamlProfileRequestContext.clearSubcontexts()" />
+ <evaluate expression="opensamlProfileRequestContext.setProfileId(opensamlProfileRequestContext.ensureInboundMessageContext().ensureMessage().getProfileId())" />
+ </on-entry>
+
+ <evaluate expression="SAMLMetadataLookup" />
+
+ <evaluate expression="InitializeRelyingPartyContexFromSAMLPeer" />
+ <evaluate expression="SelectRelyingPartyConfiguration" />
+ <evaluate expression="SelectProfileConfiguration" />
+
+ <evaluate expression="PostLookupPopulateAuditContext" />
+
+ <evaluate expression="OutputConfig" />
+ <evaluate expression="RecordResponseComplete" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="end" />
+ </action-state>
+
+ <!-- Successful terminal state (success meaning outbound message encoded). -->
+
+ <end-state id="end">
+ <on-entry>
+ <evaluate expression="WriteAuditLog" />
+ </on-entry>
+ </end-state>
+
+ <bean-import resource="dumpconfig-beans.xml" />
+
+</flow>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/admin/admin.properties b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/admin/admin.properties
index 344cb7902..8713a8178 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/admin/admin.properties
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/admin/admin.properties
@@ -24,6 +24,14 @@
#idp.resolvertest.resolveAttributes = false
#idp.resolvertest.postAuthenticationFlows =
+#idp.dumpconfig.logging = DumpConfig
+#idp.dumpconfig.accessPolicy = AccessByIPAddress
+#idp.dumpconfig.authenticated = false
+#idp.dumpconfig.nonBrowserSupported = false
+#idp.dumpconfig.defaultAuthenticationMethods =
+#idp.dumpconfig.resolveAttributes = false
+#idp.dumpconfig.postAuthenticationFlows =
+
#idp.mdquery.logging = MetadataQuery
#idp.mdquery.accessPolicy = AccessByIPAddress
#idp.mdquery.authenticated = false
diff --git a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/InterceptorAwareProfileConfiguration.java b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/InterceptorAwareProfileConfiguration.java
index b484d1cfb..4a2b8b51b 100644
--- a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/InterceptorAwareProfileConfiguration.java
+++ b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/InterceptorAwareProfileConfiguration.java
@@ -25,6 +25,7 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
import net.shibboleth.shared.annotation.constraint.NotLive;
import net.shibboleth.shared.annotation.constraint.Unmodifiable;
@@ -48,6 +49,7 @@ public interface InterceptorAwareProfileConfiguration extends ProfileConfigurati
*
* @return a set of interceptor flow IDs to enable
*/
+ @ConfigurationSetting(name="inboundInterceptorFlows")
@Nonnull @NonnullElements @NotLive @Unmodifiable List<String> getInboundInterceptorFlows(
@Nullable final ProfileRequestContext profileRequestContext);
@@ -63,6 +65,7 @@ public interface InterceptorAwareProfileConfiguration extends ProfileConfigurati
*
* @return a set of interceptor flow IDs to enable
*/
+ @ConfigurationSetting(name="outboundInterceptorFlows")
@Nonnull @NonnullElements @NotLive @Unmodifiable List<String> getOutboundInterceptorFlows(
@Nullable final ProfileRequestContext profileRequestContext);
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
index 79ec12275..b643840af 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
@@ -28,6 +28,7 @@ import javax.annotation.Nullable;
import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
import net.shibboleth.profile.config.AttributeResolvingProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NonNegative;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
import net.shibboleth.shared.annotation.constraint.NotLive;
@@ -60,6 +61,7 @@ public interface BrowserSSOProfileConfiguration
*
* @since 4.0.0
*/
+ @ConfigurationSetting(name="ignoreScoping")
boolean isIgnoreScoping(@Nullable final ProfileRequestContext profileRequestContext);
/**
@@ -71,6 +73,7 @@ public interface BrowserSSOProfileConfiguration
*
* @since 4.0.0
*/
+ @ConfigurationSetting(name="skipEndpointValidationWhenSigned")
boolean isSkipEndpointValidationWhenSigned(@Nullable final ProfileRequestContext profileRequestContext);
/**
@@ -80,6 +83,7 @@ public interface BrowserSSOProfileConfiguration
*
* @return audiences for a proxied assertion
*/
+ @ConfigurationSetting(name="proxyAudiences")
@Nonnull @NonnullElements @NotLive @Unmodifiable Set<String> getProxyAudiences(
@Nullable final ProfileRequestContext profileRequestContext);
@@ -94,6 +98,7 @@ public interface BrowserSSOProfileConfiguration
*
* @since 4.2.0
*/
+ @ConfigurationSetting(name="suppressAuthenticatingAuthority")
boolean isSuppressAuthenticatingAuthority(@Nullable final ProfileRequestContext profileRequestContext);
/**
@@ -108,6 +113,7 @@ public interface BrowserSSOProfileConfiguration
*
* @since 4.0.0
*/
+ @ConfigurationSetting(name="proxiedAuthnInstant")
boolean isProxiedAuthnInstant(@Nullable final ProfileRequestContext profileRequestContext);
/**
@@ -119,6 +125,7 @@ public interface BrowserSSOProfileConfiguration
*
* @since 4.3.0
*/
+ @ConfigurationSetting(name="requireSignedRequests")
boolean isRequireSignedRequests(@Nullable final ProfileRequestContext profileRequestContext);
/**
@@ -129,6 +136,7 @@ public interface BrowserSSOProfileConfiguration
*
* @return max lifetime of service provider should maintain a session
*/
+ @ConfigurationSetting(name="maximumSPSessionLifetime")
@Nullable Duration getMaximumSPSessionLifetime(@Nullable final ProfileRequestContext profileRequestContext);
/**
@@ -154,7 +162,6 @@ public interface BrowserSSOProfileConfiguration
*/
@Deprecated(since="5.0.0", forRemoval=true)
@NonNegative long getMaximumTokenDelegationChainLength(@Nullable final ProfileRequestContext profileRequestContext);
-
/**
* Get the function to use to translate an inbound proxied SAML 2.0 {@link AuthnContext} into the appropriate
@@ -166,6 +173,7 @@ public interface BrowserSSOProfileConfiguration
*
* @since 4.0.0
*/
+ @ConfigurationSetting(name="authnContextTranslationStrategy")
@Nullable Function<AuthnContext,Collection<Principal>> getAuthnContextTranslationStrategy(
@Nullable final ProfileRequestContext profileRequestContext);
@@ -182,6 +190,7 @@ public interface BrowserSSOProfileConfiguration
*
* @since 4.1.0
*/
+ @ConfigurationSetting(name="authnContextTranslationStrategyEx")
@Nullable Function<ProfileRequestContext,Collection<Principal>> getAuthnContextTranslationStrategyEx(
@Nullable final ProfileRequestContext profileRequestContext);
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/ECPProfileConfiguration.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/ECPProfileConfiguration.java
index b8f9bf6e0..283f04997 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/ECPProfileConfiguration.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/ECPProfileConfiguration.java
@@ -24,6 +24,7 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
import net.shibboleth.shared.annotation.constraint.NotLive;
import net.shibboleth.shared.annotation.constraint.Unmodifiable;
@@ -41,6 +42,7 @@ public interface ECPProfileConfiguration extends BrowserSSOProfileConfiguration,
*
* @since 3.3.0
*/
+ @ConfigurationSetting(name="localEvents")
@Nonnull @NonnullElements @NotLive @Unmodifiable
Set<String> getLocalEvents(@Nullable final ProfileRequestContext profileRequestContext);
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/SingleLogoutProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/SingleLogoutProfileConfiguration.java
index 526c26a61..8418999e6 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/SingleLogoutProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/SingleLogoutProfileConfiguration.java
@@ -72,7 +72,8 @@ public class SingleLogoutProfileConfiguration extends AbstractSAML2ArtifactAware
setEncryptNameIDsPredicate(new NoConfidentialityMessageChannelPredicate());
signSOAPRequestsPredicate = new org.opensaml.messaging.logic.NoIntegrityMessageChannelPredicate();
- final Predicate<MessageContext> cltsrp = new org.opensaml.messaging.logic.NoIntegrityMessageChannelPredicate().negate();
+ final Predicate<MessageContext> cltsrp =
+ new org.opensaml.messaging.logic.NoIntegrityMessageChannelPredicate().negate();
assert cltsrp!=null;
clientTLSSOAPRequestsPredicate = cltsrp;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list