[java-identity-provider] branch master updated: IDP-1421 - CAS actions should avoid raising runtime exceptions
Scott Cantor
cantor.2 at osu.edu
Mon Jul 1 11:26:03 EDT 2019
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=683be3aa3f814728acc56d4fe0a337f7a0acd113
The following commit(s) were added to refs/heads/master by this push:
new 683be3a IDP-1421 - CAS actions should avoid raising runtime exceptions
683be3a is described below
commit 683be3aa3f814728acc56d4fe0a337f7a0acd113
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Jul 1 11:25:56 2019 -0400
IDP-1421 - CAS actions should avoid raising runtime exceptions
https://issues.shibboleth.net/jira/browse/IDP-1421
Converted all beans into prototypes.
Switched where possible to non-Spring doExecute calls.
---
.../idp/cas/config/impl/ConfigLookupFunction.java | 2 +-
.../cas/flow/impl/AbstractCASProtocolAction.java | 74 ++++++++---
.../impl/AbstractOutgoingSamlMessageAction.java | 32 +++--
.../impl/BuildAuthenticationContextAction.java | 43 +++++--
.../idp/cas/flow/impl/BuildProxyChainAction.java | 59 ++++++---
.../flow/impl/BuildRelyingPartyContextAction.java | 64 +++++++---
.../flow/impl/BuildSAMLMetadataContextAction.java | 47 +++++--
.../BuildSamlValidationFailureMessageAction.java | 12 +-
.../BuildSamlValidationSuccessMessageAction.java | 22 ++--
.../flow/impl/CheckProxyAuthorizationAction.java | 40 ++++--
.../idp/cas/flow/impl/GrantProxyTicketAction.java | 116 ++++++++++++------
.../cas/flow/impl/GrantServiceTicketAction.java | 136 ++++++++++++++-------
.../idp/cas/flow/impl/InitializeLoginAction.java | 17 ++-
.../idp/cas/flow/impl/InitializeProxyAction.java | 34 +++---
.../cas/flow/impl/InitializeValidateAction.java | 19 ++-
.../cas/flow/impl/PopulateProtocolErrorAction.java | 38 ++++--
.../PrepareTicketValidationResponseAction.java | 63 +++++++---
.../cas/flow/impl/ProcessSamlMessageAction.java | 25 ++--
.../flow/impl/PublishProtocolMessageAction.java | 28 +++--
.../impl/UpdateIdPSessionWithSPSessionAction.java | 58 ++++++---
.../cas/flow/impl/ValidateProxyCallbackAction.java | 95 +++++++++-----
.../idp/cas/flow/impl/ValidateRenewAction.java | 50 +++++---
.../idp/cas/flow/impl/ValidateTicketAction.java | 101 ++++++++++-----
.../cas/flow/impl/WriteValidateResponseAction.java | 45 ++++---
.../impl/BuildRelyingPartyContextActionTest.java | 8 +-
.../system/flows/cas/cas-abstract-beans.xml | 35 +++---
.../system/flows/cas/login/login-beans.xml | 25 ++--
.../system/flows/cas/proxy/proxy-beans.xml | 7 +-
.../cas/proxyValidate/proxyValidate-beans.xml | 2 +-
.../flows/cas/samlValidate/samlValidate-beans.xml | 24 ++--
.../system/flows/cas/validate-abstract-beans.xml | 17 +--
.../system/flows/cas/validate/validate-beans.xml | 14 ++-
32 files changed, 889 insertions(+), 463 deletions(-)
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ConfigLookupFunction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ConfigLookupFunction.java
index 6ff3869..256cba5 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ConfigLookupFunction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ConfigLookupFunction.java
@@ -50,7 +50,7 @@ public class ConfigLookupFunction<T extends AbstractProtocolConfiguration>
/** {@inheritDoc} */
@Nullable public T apply(@Nullable final ProfileRequestContext profileRequestContext) {
if (profileRequestContext != null) {
- final RelyingPartyContext rpContext = profileRequestContext.getSubcontext(RelyingPartyContext.class, false);
+ final RelyingPartyContext rpContext = profileRequestContext.getSubcontext(RelyingPartyContext.class);
if (rpContext != null && configClass.isInstance(rpContext.getProfileConfig())) {
return configClass.cast(rpContext.getProfileConfig());
}
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/AbstractCASProtocolAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/AbstractCASProtocolAction.java
index d5aaaff..45be3fc 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/AbstractCASProtocolAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/AbstractCASProtocolAction.java
@@ -20,6 +20,7 @@ package net.shibboleth.idp.cas.flow.impl;
import java.util.function.Function;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.cas.protocol.ProtocolContext;
import net.shibboleth.idp.cas.service.Service;
@@ -29,7 +30,13 @@ import net.shibboleth.idp.cas.ticket.TicketContext;
import net.shibboleth.idp.profile.AbstractProfileAction;
import net.shibboleth.utilities.java.support.logic.Constraint;
import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.EventException;
+import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.webflow.execution.Event;
+import org.springframework.webflow.execution.RequestContext;
/**
* Base class for CAS protocol actions.
@@ -41,7 +48,11 @@ import org.opensaml.profile.context.ProfileRequestContext;
*/
public abstract class AbstractCASProtocolAction<RequestType, ResponseType> extends AbstractProfileAction {
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractCASProtocolAction.class);
+
/** Looks up a CAS protocol context from IdP profile request context. */
+ @Nonnull
private final Function<ProfileRequestContext,ProtocolContext<RequestType,ResponseType>> protocolLookupFunction;
/** Constructor. */
@@ -54,12 +65,14 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @return CAS request
+ *
+ * @throws EventException to propagate an event
*/
- @Nonnull
- protected RequestType getCASRequest(final ProfileRequestContext prc) {
+ @Nonnull protected RequestType getCASRequest(@Nullable final ProfileRequestContext prc) throws EventException {
final RequestType request = getProtocolContext(prc).getRequest();
if (request == null) {
- throw new IllegalStateException("CAS protocol request not found");
+ log.error("{} CAS protocol request not found", getLogPrefix());
+ throw new EventException(EventIds.INVALID_MSG_CTX);
}
return request;
}
@@ -69,8 +82,11 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @param request CAS request
+ *
+ * @throws EventException to propagate an event
*/
- protected void setCASRequest(final ProfileRequestContext prc, @Nonnull final RequestType request) {
+ protected void setCASRequest(@Nullable final ProfileRequestContext prc, @Nonnull final RequestType request)
+ throws EventException {
getProtocolContext(prc).setRequest(Constraint.isNotNull(request, "CAS request cannot be null"));
}
@@ -79,12 +95,14 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @return CAS response
+ *
+ * @throws EventException to propagate an event
*/
- @Nonnull
- protected ResponseType getCASResponse(final ProfileRequestContext prc) {
+ @Nonnull protected ResponseType getCASResponse(@Nullable final ProfileRequestContext prc) throws EventException {
final ResponseType response = getProtocolContext(prc).getResponse();
if (response == null) {
- throw new IllegalStateException("CAS protocol response not found");
+ log.error("{} CAS protocol response not found", getLogPrefix());
+ throw new EventException(EventIds.INVALID_MSG_CTX);
}
return response;
}
@@ -94,8 +112,11 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @param response CAS response
+ *
+ * @throws EventException to propagate an event
*/
- protected void setCASResponse(final ProfileRequestContext prc, @Nonnull final ResponseType response) {
+ protected void setCASResponse(@Nullable final ProfileRequestContext prc, @Nonnull final ResponseType response)
+ throws EventException {
getProtocolContext(prc).setResponse(Constraint.isNotNull(response, "CAS response cannot be null"));
}
@@ -104,11 +125,14 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @return CAS ticket
+ *
+ * @throws EventException to propagate an event
*/
- @Nonnull protected Ticket getCASTicket(final ProfileRequestContext prc) {
+ @Nonnull protected Ticket getCASTicket(final ProfileRequestContext prc) throws EventException {
final TicketContext context = getProtocolContext(prc).getSubcontext(TicketContext.class);
if (context == null || context.getTicket() == null) {
- throw new IllegalStateException("CAS protocol ticket not found");
+ log.error("{} CAS protocol ticket not found", getLogPrefix());
+ throw new EventException(EventIds.INVALID_MSG_CTX);
}
return context.getTicket();
}
@@ -118,8 +142,11 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @param ticket CAS ticket
+ *
+ * @throws EventException to propagate an event
*/
- protected void setCASTicket(final ProfileRequestContext prc, @Nonnull final Ticket ticket) {
+ protected void setCASTicket(@Nullable final ProfileRequestContext prc, @Nonnull final Ticket ticket)
+ throws EventException {
getProtocolContext(prc).addSubcontext(
new TicketContext(Constraint.isNotNull(ticket, "CAS ticket cannot be null")));
}
@@ -129,11 +156,14 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @return CAS service
+ *
+ * @throws EventException to propagate an event
*/
- @Nonnull protected Service getCASService(final ProfileRequestContext prc) {
+ @Nonnull protected Service getCASService(@Nullable final ProfileRequestContext prc) throws EventException {
final ServiceContext context = getProtocolContext(prc).getSubcontext(ServiceContext.class);
if (context == null || context.getService() == null) {
- throw new IllegalStateException("CAS protocol service not found");
+ log.error("{} CAS protocol service not found", getLogPrefix());
+ throw new EventException(EventIds.INVALID_MSG_CTX);
}
return context.getService();
}
@@ -143,8 +173,11 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @param service CAS service
+ *
+ * @throws EventException to propagate an event
*/
- protected void setCASService(final ProfileRequestContext prc, @Nonnull final Service service) {
+ protected void setCASService(@Nullable final ProfileRequestContext prc, @Nonnull final Service service)
+ throws EventException {
getProtocolContext(prc).addSubcontext(
new ServiceContext(Constraint.isNotNull(service, "CAS service cannot be null")));
}
@@ -154,12 +187,17 @@ public abstract class AbstractCASProtocolAction<RequestType, ResponseType> exten
*
* @param prc profile request context
* @return CAS protocol context
+ *
+ * @throws EventException to propagate an event
*/
- @Nonnull protected ProtocolContext<RequestType, ResponseType> getProtocolContext(final ProfileRequestContext prc) {
- final ProtocolContext<RequestType, ResponseType> casCtx = protocolLookupFunction.apply(prc);
+ @Nonnull protected ProtocolContext<RequestType,ResponseType> getProtocolContext(
+ @Nullable final ProfileRequestContext prc) throws EventException {
+ final ProtocolContext<RequestType,ResponseType> casCtx = protocolLookupFunction.apply(prc);
if (casCtx == null) {
- throw new IllegalArgumentException("CAS ProtocolContext not found in ProfileRequestContext");
+ log.error("{} CAS ProtocolContext not found in ProfileRequestContext", getLogPrefix());
+ throw new EventException(EventIds.INVALID_PROFILE_CTX);
}
return casCtx;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/AbstractOutgoingSamlMessageAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/AbstractOutgoingSamlMessageAction.java
index 78977ae..2933395 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/AbstractOutgoingSamlMessageAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/AbstractOutgoingSamlMessageAction.java
@@ -23,7 +23,6 @@ import javax.xml.namespace.QName;
import net.shibboleth.idp.cas.protocol.ProtocolError;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
-import net.shibboleth.idp.profile.ActionSupport;
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;
@@ -33,6 +32,8 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.core.xml.util.XMLObjectSupport;
import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.common.SAMLObject;
import org.opensaml.saml.common.SAMLObjectBuilder;
@@ -43,8 +44,6 @@ import org.opensaml.soap.messaging.context.SOAP11Context;
import org.opensaml.soap.soap11.Body;
import org.opensaml.soap.soap11.Envelope;
import org.opensaml.soap.util.SOAPConstants;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Base class for all actions that build SAML {@link Response} messages for output.
@@ -90,8 +89,6 @@ public abstract class AbstractOutgoingSamlMessageAction extends
}
}
-
-
/**
* Build the SAML object.
*
@@ -108,15 +105,14 @@ public abstract class AbstractOutgoingSamlMessageAction extends
}
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
final MessageContext<SAMLObject> msgContext = new MessageContext<>();
try {
- msgContext.setMessage(buildSamlResponse(springRequestContext, profileRequestContext));
- } catch (final IllegalStateException e) {
- return ProtocolError.IllegalState.event(this);
+ msgContext.setMessage(buildSamlResponse(profileRequestContext));
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.IllegalState.event(this));
+ return;
}
final SAMLBindingContext bindingContext = new SAMLBindingContext();
bindingContext.setBindingUri(outgoingBinding.getId());
@@ -131,18 +127,18 @@ public abstract class AbstractOutgoingSamlMessageAction extends
msgContext.addSubcontext(soapCtx);
profileRequestContext.setOutboundMessageContext(msgContext);
-
- return ActionSupport.buildProceedEvent(this);
}
/**
* Build the SAML response.
*
- * @param springRequestContext Spring request context
* @param profileRequestContext profile request context
+ *
* @return SAML response
+ *
+ * @throws EventException to signal an event
*/
- protected abstract Response buildSamlResponse(
- @Nonnull RequestContext springRequestContext,
- @Nonnull ProfileRequestContext<SAMLObject, SAMLObject> profileRequestContext);
-}
+ @Nonnull protected abstract Response buildSamlResponse(
+ @Nonnull final ProfileRequestContext<SAMLObject,SAMLObject> profileRequestContext) throws EventException;
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildAuthenticationContextAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildAuthenticationContextAction.java
index 9a85c64..8028677 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildAuthenticationContextAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildAuthenticationContextAction.java
@@ -18,6 +18,7 @@
package net.shibboleth.idp.cas.flow.impl;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.cas.config.impl.ConfigLookupFunction;
@@ -25,29 +26,50 @@ import net.shibboleth.idp.cas.config.impl.LoginConfiguration;
import net.shibboleth.idp.cas.protocol.ServiceTicketRequest;
import net.shibboleth.idp.cas.protocol.ServiceTicketResponse;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Builds an authentication context from an incoming {@link ServiceTicketRequest} message.
*
* @author Marvin S. Addison
*/
-public class BuildAuthenticationContextAction extends
- AbstractCASProtocolAction<ServiceTicketRequest, ServiceTicketResponse> {
+public class BuildAuthenticationContextAction
+ extends AbstractCASProtocolAction<ServiceTicketRequest,ServiceTicketResponse> {
/** Profile configuration lookup function. */
- private final ConfigLookupFunction<LoginConfiguration> configLookupFunction =
- new ConfigLookupFunction<>(LoginConfiguration.class);
+ @Nonnull private final ConfigLookupFunction<LoginConfiguration> configLookupFunction;
- @Nonnull
+ /** Stores off CAS request. */
+ @Nullable private ServiceTicketRequest request;
+
+ /** Constructor. */
+ public BuildAuthenticationContextAction() {
+ configLookupFunction = new ConfigLookupFunction<>(LoginConfiguration.class);
+ }
+
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ try {
+ request = getCASRequest(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
+
+ return true;
+ }
+
@Override
- protected Event doExecute(@Nonnull final RequestContext springRequestContext,
- @Nonnull final ProfileRequestContext profileRequestContext){
+ @Nonnull protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
final AuthenticationContext ac = new AuthenticationContext();
- ac.setForceAuthn(getCASRequest(profileRequestContext).isRenew());
+ ac.setForceAuthn(request.isRenew());
ac.setIsPassive(false);
if (!ac.isForceAuthn()) {
@@ -59,7 +81,6 @@ public class BuildAuthenticationContextAction extends
profileRequestContext.addSubcontext(ac, true);
profileRequestContext.setBrowserProfile(true);
- return null;
}
}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainAction.java
index 975612e..3f614cf 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildProxyChainAction.java
@@ -18,6 +18,7 @@
package net.shibboleth.idp.cas.flow.impl;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.cas.protocol.ProtocolError;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
@@ -27,11 +28,12 @@ import net.shibboleth.idp.cas.ticket.ProxyTicket;
import net.shibboleth.idp.cas.ticket.Ticket;
import net.shibboleth.idp.cas.ticket.TicketServiceEx;
import net.shibboleth.utilities.java.support.logic.Constraint;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Action that builds the chain of visited proxies for a successful proxy ticket validation event. Possible outcomes:
@@ -45,35 +47,52 @@ import org.springframework.webflow.execution.RequestContext;
* @author Marvin S. Addison
*/
public class BuildProxyChainAction
- extends AbstractCASProtocolAction<TicketValidationRequest, TicketValidationResponse> {
+ extends AbstractCASProtocolAction<TicketValidationRequest,TicketValidationResponse> {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(BuildProxyChainAction.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BuildProxyChainAction.class);
/** Manages CAS tickets. */
- @Nonnull
- private final TicketServiceEx ticketServiceEx;
-
+ @Nonnull private final TicketServiceEx ticketServiceEx;
+
+ /** Response. */
+ @Nullable private TicketValidationResponse response;
+
+ /** Ticket. */
+ @Nullable private Ticket ticket;
/**
- * Creates a new instance.
+ * Constructor.
*
* @param ticketService Ticket service component.
*/
public BuildProxyChainAction(@Nonnull final TicketServiceEx ticketService) {
ticketServiceEx = Constraint.isNotNull(ticketService, "TicketService cannot be null");
}
+
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ try {
+ response = getCASResponse(profileRequestContext);
+ ticket = getCASTicket(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
+
+ return true;
+ }
- @Nonnull
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- final TicketValidationResponse response = getCASResponse(profileRequestContext);
- final Ticket ticket = getCASTicket(profileRequestContext);
if (!(ticket instanceof ProxyTicket)) {
- return ProtocolError.InvalidTicketType.event(this);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.InvalidTicketType.event(this));
+ return;
}
final ProxyTicket pt = (ProxyTicket) ticket;
ProxyGrantingTicket pgt;
@@ -81,13 +100,13 @@ public class BuildProxyChainAction
do {
pgt = ticketServiceEx.fetchProxyGrantingTicket(pgtId);
if (pgt == null) {
- log.debug("PGT {} not found", pgtId);
- return ProtocolError.BrokenProxyChain.event(this);
+ log.debug("{} PGT {} not found", getLogPrefix(), pgtId);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.BrokenProxyChain.event(this));
+ return;
}
response.addProxy(pgt.getService());
pgtId = pgt.getParentId();
} while (pgtId != null);
-
- return null;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildRelyingPartyContextAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildRelyingPartyContextAction.java
index 0ea94d2..3a685dd 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildRelyingPartyContextAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildRelyingPartyContextAction.java
@@ -28,13 +28,16 @@ import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.service.Service;
import net.shibboleth.idp.cas.service.ServiceRegistry;
import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.logic.Constraint;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
+import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Creates the {@link RelyingPartyContext} as a child of the {@link ProfileRequestContext}. The component queries
@@ -46,16 +49,16 @@ import org.springframework.webflow.execution.RequestContext;
public class BuildRelyingPartyContextAction extends AbstractCASProtocolAction {
/** Name of group to which unverified services belong. */
- public static final String UNVERIFIED_GROUP = "unverified";
+ @Nonnull @NotEmpty public static final String UNVERIFIED_GROUP = "unverified";
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(BuildRelyingPartyContextAction.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BuildRelyingPartyContextAction.class);
/** List of registries to query for verified CAS services (relying parties). */
- @Nonnull
- @NotEmpty
- private final List<ServiceRegistry> serviceRegistries;
-
+ @Nonnull @NonnullElements @NotEmpty private final List<ServiceRegistry> serviceRegistries;
+
+ /** Request. */
+ @Nullable private Object request;
/**
* Creates a new instance.
@@ -65,15 +68,29 @@ public class BuildRelyingPartyContextAction extends AbstractCASProtocolAction {
public BuildRelyingPartyContextAction(@Nonnull @NotEmpty final ServiceRegistry ... registries) {
serviceRegistries = Arrays.asList(Constraint.isNotEmpty(registries, "Service registries cannot be null"));
}
+
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ try {
+ request = getCASRequest(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
+
+ return true;
+ }
+
- @Nonnull
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ @Nonnull protected void doExecute(final @Nonnull ProfileRequestContext profileRequestContext) {
final String serviceURL;
- final Object request = getCASRequest(profileRequestContext);
+
if (request instanceof ServiceTicketRequest) {
serviceURL = ((ServiceTicketRequest) request).getService();
} else if (request instanceof ProxyTicketRequest) {
@@ -81,22 +98,30 @@ public class BuildRelyingPartyContextAction extends AbstractCASProtocolAction {
} else if (request instanceof TicketValidationRequest) {
serviceURL = ((TicketValidationRequest) request).getService();
} else {
- throw new IllegalStateException("Service URL not found in flow state");
+ log.warn("{} Service URL not found in flow state", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+ return;
}
+
Service service = query(serviceURL);
final RelyingPartyContext rpc = new RelyingPartyContext();
rpc.setVerified(service != null);
rpc.setRelyingPartyId(serviceURL);
if (service != null) {
- log.debug("Setting up RP context for verified relying party {}", service);
+ log.debug("{} Setting up RP context for verified relying party {}", getLogPrefix(), service);
} else {
service = new Service(serviceURL, UNVERIFIED_GROUP, false);
- log.debug("Setting up RP context for unverified relying party {}", service);
+ log.debug("{} Setting up RP context for unverified relying party {}", getLogPrefix(), service);
}
- log.debug("Relying party context created for {}", service);
+ log.debug("{} Relying party context created for {}", getLogPrefix(), service);
+
profileRequestContext.addSubcontext(rpc);
- setCASService(profileRequestContext, service);
- return null;
+
+ try {
+ setCASService(profileRequestContext, service);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ }
}
/**
@@ -115,6 +140,7 @@ public class BuildRelyingPartyContextAction extends AbstractCASProtocolAction {
return service;
}
}
+
return null;
}
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSAMLMetadataContextAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSAMLMetadataContextAction.java
index e42b2c5..e70095a 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSAMLMetadataContextAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSAMLMetadataContextAction.java
@@ -18,16 +18,19 @@
package net.shibboleth.idp.cas.flow.impl;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.cas.protocol.ProtocolError;
import net.shibboleth.idp.cas.service.Service;
import net.shibboleth.idp.cas.service.impl.ServiceEntityDescriptor;
+import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.profile.context.RelyingPartyContext;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
import org.opensaml.saml.saml2.metadata.EntityDescriptor;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Builds a {@link SAMLMetadataContext} child of {@link RelyingPartyContext} to facilitate relying party selection
@@ -41,23 +44,45 @@ import org.springframework.webflow.execution.RequestContext;
*/
public class BuildSAMLMetadataContextAction extends AbstractCASProtocolAction {
+ /** CAS service. */
+ @Nullable private Service service;
+
+ /** RelyingPartyContext. */
+ @Nullable private RelyingPartyContext rpCtx;
+
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
- final RelyingPartyContext rpCtx = profileRequestContext.getSubcontext(RelyingPartyContext.class);
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ try {
+ service = getCASService(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
+
+ rpCtx = profileRequestContext.getSubcontext(RelyingPartyContext.class);
if (rpCtx == null) {
- throw new IllegalStateException("RelyingPartyContext not found");
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_RELYING_PARTY_CTX);
+ return false;
}
+
+ return true;
+ }
+
+ @Override
+ protected void doExecute(final @Nonnull ProfileRequestContext profileRequestContext) {
+
final SAMLMetadataContext mdCtx = new SAMLMetadataContext();
- final Service service = getCASService(profileRequestContext);
final EntityDescriptor entity = service.getEntityDescriptor() != null
? service.getEntityDescriptor()
: new ServiceEntityDescriptor(service);
mdCtx.setEntityDescriptor(entity);
mdCtx.setRoleDescriptor(service.getRoleDescriptor());
+
rpCtx.setRelyingPartyIdContextTree(mdCtx);
-
- return null;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSamlValidationFailureMessageAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSamlValidationFailureMessageAction.java
index bb242fb..ad93c12 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSamlValidationFailureMessageAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSamlValidationFailureMessageAction.java
@@ -24,13 +24,14 @@ import javax.xml.namespace.QName;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
+
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.common.SAMLObject;
import org.opensaml.saml.saml1.core.Response;
import org.opensaml.saml.saml1.core.Status;
import org.opensaml.saml.saml1.core.StatusCode;
import org.opensaml.saml.saml1.core.StatusMessage;
-import org.springframework.webflow.execution.RequestContext;
/**
* Creates the SAML response message for failed ticket validation at the <code>/samlValidate</code> URI.
@@ -39,11 +40,9 @@ import org.springframework.webflow.execution.RequestContext;
*/
public class BuildSamlValidationFailureMessageAction extends AbstractOutgoingSamlMessageAction {
- @Nonnull
@Override
- protected Response buildSamlResponse(
- @Nonnull final RequestContext springRequestContext,
- @Nonnull final ProfileRequestContext<SAMLObject, SAMLObject> profileRequestContext) {
+ @Nonnull protected Response buildSamlResponse(
+ @Nonnull final ProfileRequestContext<SAMLObject,SAMLObject> profileRequestContext) throws EventException {
final TicketValidationRequest request = getCASRequest(profileRequestContext);
final TicketValidationResponse validationResponse = getCASResponse(profileRequestContext);
@@ -61,4 +60,5 @@ public class BuildSamlValidationFailureMessageAction extends AbstractOutgoingSam
return response;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSamlValidationSuccessMessageAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSamlValidationSuccessMessageAction.java
index cf02a88..cbcb258 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSamlValidationSuccessMessageAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSamlValidationSuccessMessageAction.java
@@ -21,10 +21,12 @@ import java.time.Instant;
import javax.annotation.Nonnull;
+import net.shibboleth.idp.cas.protocol.ProtocolError;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
import net.shibboleth.idp.cas.ticket.Ticket;
import net.shibboleth.idp.cas.ticket.TicketState;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
import net.shibboleth.utilities.java.support.security.IdentifierGenerationStrategy;
@@ -32,6 +34,7 @@ import net.shibboleth.utilities.java.support.security.IdentifierGenerationStrate
import org.opensaml.core.xml.XMLObjectBuilder;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.core.xml.schema.XSString;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.common.SAMLObject;
import org.opensaml.saml.common.SAMLVersion;
@@ -52,7 +55,6 @@ import org.opensaml.saml.saml1.core.Subject;
import org.opensaml.saml.saml1.core.SubjectConfirmation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.RequestContext;
/**
* Creates the SAML response message for successful ticket validation at the <code>/samlValidate</code> URI.
@@ -80,27 +82,24 @@ public class BuildSamlValidationSuccessMessageAction extends AbstractOutgoingSam
/**
- * Creates a new instance with required parameters.
+ * Constructor.
*
* @param strategy SAML identifier generation strategy.
* @param id IdP entity ID.
*/
- public BuildSamlValidationSuccessMessageAction(final IdentifierGenerationStrategy strategy, final String id) {
+ public BuildSamlValidationSuccessMessageAction(@Nonnull final IdentifierGenerationStrategy strategy,
+ @Nonnull @NotEmpty final String id) {
Constraint.isNotNull(strategy, "IdentifierGenerationStrategy cannot be null");
identifierGenerationStrategy = strategy;
entityID = Constraint.isNotNull(StringSupport.trimOrNull(id), "EntityID cannot be null");
attrValueBuilder = XMLObjectProviderRegistrySupport.getBuilderFactory().<XSString>getBuilderOrThrow(
XSString.TYPE_NAME);
-
}
-
- @Nonnull
@Override
- protected Response buildSamlResponse(
- @Nonnull final RequestContext springRequestContext,
- @Nonnull final ProfileRequestContext<SAMLObject, SAMLObject> profileRequestContext) {
+ @Nonnull protected Response buildSamlResponse(
+ @Nonnull final ProfileRequestContext<SAMLObject,SAMLObject> profileRequestContext) throws EventException {
final Instant now = Instant.now();
@@ -109,7 +108,7 @@ public class BuildSamlValidationSuccessMessageAction extends AbstractOutgoingSam
final Ticket ticket = getCASTicket(profileRequestContext);
final TicketState state = ticket.getTicketState();
if (state == null) {
- throw new IllegalStateException("TicketState cannot be null");
+ throw new EventException(ProtocolError.IllegalState.name());
}
log.debug("Building SAML response for {} in IdP session {}", request.getService(), state.getSessionId());
@@ -210,4 +209,5 @@ public class BuildSamlValidationSuccessMessageAction extends AbstractOutgoingSam
stringValue.setValue(value);
return stringValue;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/CheckProxyAuthorizationAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/CheckProxyAuthorizationAction.java
index 12e8776..6ca0605 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/CheckProxyAuthorizationAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/CheckProxyAuthorizationAction.java
@@ -18,15 +18,17 @@
package net.shibboleth.idp.cas.flow.impl;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.cas.protocol.ProtocolError;
import net.shibboleth.idp.cas.service.Service;
import net.shibboleth.idp.cas.service.ServiceContext;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Checks the current {@link ServiceContext} to determine whether the service/relying party is authorized to proxy.
@@ -41,18 +43,34 @@ import org.springframework.webflow.execution.RequestContext;
public class CheckProxyAuthorizationAction extends AbstractCASProtocolAction {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(CheckProxyAuthorizationAction.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(CheckProxyAuthorizationAction.class);
+ /** CAS service. */
+ @Nullable private Service service;
+
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ try {
+ service = getCASService(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- final Service service = getCASService(profileRequestContext);
if (!service.isAuthorizedToProxy()) {
- log.info("{} is not authorized to proxy", service.getName());
- return ProtocolError.ProxyNotAuthorized.event(this);
+ log.info("{} Service '{}' is not authorized to proxy", getLogPrefix(), service.getName());
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.ProxyNotAuthorized.event(this));
}
- return null;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketAction.java
index ff315f6..6c6810f 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketAction.java
@@ -21,6 +21,7 @@ import java.time.Instant;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import com.google.common.base.Predicates;
import net.shibboleth.idp.cas.config.impl.ConfigLookupFunction;
@@ -31,6 +32,7 @@ import net.shibboleth.idp.cas.protocol.ProxyTicketResponse;
import net.shibboleth.idp.cas.ticket.ProxyGrantingTicket;
import net.shibboleth.idp.cas.ticket.ProxyTicket;
import net.shibboleth.idp.cas.ticket.TicketServiceEx;
+import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.profile.config.SecurityConfiguration;
import net.shibboleth.idp.session.IdPSession;
import net.shibboleth.idp.session.SessionException;
@@ -40,11 +42,13 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
+import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Generates and stores a CAS protocol proxy ticket. Possible outcomes:
@@ -59,8 +63,7 @@ import org.springframework.webflow.execution.RequestContext;
public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicketRequest, ProxyTicketResponse> {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(GrantProxyTicketAction.class);
-
+ @Nonnull private final Logger log = LoggerFactory.getLogger(GrantProxyTicketAction.class);
/** Profile configuration lookup function. */
@Nonnull private final ConfigLookupFunction<ProxyConfiguration> configLookupFunction;
@@ -74,15 +77,26 @@ public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicke
/** Whether to resolve and validate IdP session as part of granting a proxy ticket. */
@Nonnull private Predicate<ProfileRequestContext> validateIdPSessionPredicate;
+ /** Profile config. */
+ @Nullable private ProxyConfiguration proxyConfig;
+
+ /** Security config. */
+ @Nullable private SecurityConfiguration securityConfig;
+
+ /** CAS ticket. */
+ @Nullable private ProxyGrantingTicket pgt;
+
+ /** CAS request. */
+ @Nullable private ProxyTicketRequest request;
/**
- * Creates a new instance.
+ * Constructor.
*
* @param ticketService Ticket service component.
* @param resolver session resolver
*/
- public GrantProxyTicketAction(
- @Nonnull final TicketServiceEx ticketService, @Nonnull final SessionResolver resolver) {
+ public GrantProxyTicketAction(@Nonnull final TicketServiceEx ticketService,
+ @Nonnull final SessionResolver resolver) {
casTicketService = Constraint.isNotNull(ticketService, "TicketService cannot be null");
sessionResolver = Constraint.isNotNull(resolver, "SessionResolver cannot be null");
@@ -106,66 +120,90 @@ public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicke
validateIdPSessionPredicate = Constraint.isNotNull(predicate, "Session validation condition cannot be null");
}
- /** {@inheritDoc} */
@Override
- @Nonnull
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
-
- final ProxyGrantingTicket pgt = (ProxyGrantingTicket) getCASTicket(profileRequestContext);
- if (pgt == null || pgt.getExpirationInstant().isBefore(Instant.now())) {
- return ProtocolError.TicketExpired.event(this);
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ proxyConfig = configLookupFunction.apply(profileRequestContext);
+ if (proxyConfig == null) {
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return false;
}
- final ProxyConfiguration config = configLookupFunction.apply(profileRequestContext);
- if (config == null) {
- log.warn("Proxy ticket configuration undefined");
- return ProtocolError.IllegalState.event(this);
+
+ securityConfig = proxyConfig.getSecurityConfiguration(profileRequestContext);
+ if (securityConfig == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_SEC_CFG);
+ return false;
}
- final SecurityConfiguration securityConfiguration = config.getSecurityConfiguration(profileRequestContext);
- if (securityConfiguration == null || securityConfiguration.getIdGenerator() == null) {
- log.warn("Invalid proxy ticket configuration: SecurityConfiguration#idGenerator undefined");
- return ProtocolError.IllegalState.event(this);
+ try {
+ request = getCASRequest(profileRequestContext);
+ pgt = (ProxyGrantingTicket) getCASTicket(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
}
+
+ return true;
+ }
+
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ if (pgt.getExpirationInstant().isBefore(Instant.now())) {
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketExpired.event(this));
+ return;
+ }
+
if (validateIdPSessionPredicate.test(profileRequestContext)) {
IdPSession session = null;
try {
- log.debug("Attempting to retrieve session {}", pgt.getSessionId());
+ log.debug("{} Attempting to retrieve session {}", getLogPrefix(), pgt.getSessionId());
session = sessionResolver.resolveSingle(new CriteriaSet(new SessionIdCriterion(pgt.getSessionId())));
} catch (final ResolverException e) {
- log.warn("IdPSession resolution error: {}", e);
+ log.warn("{} IdPSession resolution error: {}", getLogPrefix(), e);
}
boolean expired = true;
if (session == null) {
- log.info("IdPSession {} not found", pgt.getSessionId());
+ log.info("{} IdPSession {} not found", getLogPrefix(), pgt.getSessionId());
} else {
try {
expired = !session.checkTimeout();
- log.debug("Session {} expired={}", pgt.getSessionId(), expired);
+ log.debug("{} Session {} expired={}", getLogPrefix(), pgt.getSessionId(), expired);
} catch (final SessionException e) {
- log.warn("Error performing session timeout check: {}. Assuming session has expired.", e);
+ log.warn("{} Error performing session timeout check: {}. Assuming session has expired.",
+ getLogPrefix(), e);
}
}
if (expired) {
- return ProtocolError.SessionExpired.event(this);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.SessionExpired.event(this));
+ return;
}
}
- final ProxyTicketRequest request = getCASRequest(profileRequestContext);
final ProxyTicket pt;
try {
- log.debug("Granting proxy ticket for {}", request.getTargetService());
+ log.debug("{} Granting proxy ticket for {}", getLogPrefix(), request.getTargetService());
pt = casTicketService.createProxyTicket(
- securityConfiguration.getIdGenerator().generateIdentifier(),
- Instant.now().plus(config.getTicketValidityPeriod(profileRequestContext)),
+ securityConfig.getIdGenerator().generateIdentifier(),
+ Instant.now().plus(proxyConfig.getTicketValidityPeriod(profileRequestContext)),
pgt,
request.getTargetService());
} catch (final RuntimeException e) {
log.error("Failed granting proxy ticket due to error.", e);
- return ProtocolError.TicketCreationError.event(this);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketCreationError.event(this));
+ return;
}
- log.info("Granted proxy ticket for {}", request.getTargetService());
- setCASResponse(profileRequestContext, new ProxyTicketResponse(pt.getId()));
- return null;
+
+ try {
+ setCASResponse(profileRequestContext, new ProxyTicketResponse(pt.getId()));
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return;
+ }
+
+ log.info("{} Granted proxy ticket for {}", getLogPrefix(), request.getTargetService());
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantServiceTicketAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantServiceTicketAction.java
index fa218e9..0afe3c1 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantServiceTicketAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantServiceTicketAction.java
@@ -21,8 +21,10 @@ import java.time.Instant;
import java.util.function.Function;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.authn.AuthenticationResult;
+import net.shibboleth.idp.authn.AuthnEventIds;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.authn.context.SubjectContext;
import net.shibboleth.idp.authn.context.navigate.SubjectContextPrincipalLookupFunction;
@@ -34,16 +36,18 @@ import net.shibboleth.idp.cas.protocol.ServiceTicketResponse;
import net.shibboleth.idp.cas.ticket.ServiceTicket;
import net.shibboleth.idp.cas.ticket.TicketServiceEx;
import net.shibboleth.idp.cas.ticket.TicketState;
+import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.profile.config.SecurityConfiguration;
import net.shibboleth.idp.session.IdPSession;
import net.shibboleth.idp.session.context.SessionContext;
import net.shibboleth.utilities.java.support.logic.Constraint;
import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
+import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Generates and stores a CAS protocol service ticket. Possible outcomes:
@@ -74,9 +78,23 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
/** Manages CAS tickets. */
@Nonnull private final TicketServiceEx ticketServiceEx;
+ /** Profile config. */
+ @Nullable private LoginConfiguration loginConfig;
+
+ /** Security config. */
+ @Nullable private SecurityConfiguration securityConfig;
+
+ /** IdP's session. */
+ @Nullable private IdPSession session;
+
+ /** Authentication result. */
+ @Nullable private AuthenticationResult authnResult;
+
+ /** CAS request. */
+ @Nullable private ServiceTicketRequest request;
/**
- * Creates a new instance.
+ * Constructor.
*
* @param ticketService Ticket service component.
*/
@@ -90,72 +108,105 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
new ChildContextLookup<>(SubjectContext.class));
}
- /** {@inheritDoc} */
- @Nonnull
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
-
- final ServiceTicketRequest request = getCASRequest(profileRequestContext);
- final IdPSession session = getIdPSession(profileRequestContext);
- final LoginConfiguration config = configLookupFunction.apply(profileRequestContext);
- if (config == null) {
- throw new IllegalStateException("Service ticket configuration undefined");
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
}
- final SecurityConfiguration securityConfiguration = config.getSecurityConfiguration(profileRequestContext);
- if (securityConfiguration == null || securityConfiguration == null) {
- throw new IllegalStateException(
- "Invalid service ticket configuration: SecurityConfiguration#idGenerator undefined");
+ loginConfig = configLookupFunction.apply(profileRequestContext);
+ if (loginConfig == null) {
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return false;
}
+
+ securityConfig = loginConfig.getSecurityConfiguration(profileRequestContext);
+ if (securityConfig == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_SEC_CFG);
+ return false;
+ }
+
+ try {
+ request = getCASRequest(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
+
+ session = getIdPSession(profileRequestContext);
+ if (session == null) {
+ // TODO: I think this should be revisited, unclear why the TicketState later needs this.
+ // It may be needed specifically if the check below for an active AuthnResult fails, but that's
+ // a secondary requirement that would only happen when absolutely needed.
+ log.warn("{} No IdP session found", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
final AuthenticationContext authnCtx = authnCtxLookupFunction.apply(profileRequestContext);
- final AuthenticationResult authnResult;
if (authnCtx != null) {
authnResult = authnCtx.getAuthenticationResult();
} else {
- authnResult = getLatestAuthenticationResult(session);
+ authnResult = getLatestAuthenticationResult();
+ }
+
+ if (authnResult == null) {
+ log.warn("{} No AuthenticationResult found", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
+ return false;
}
+
+ return true;
+ }
+
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
final ServiceTicket ticket;
try {
- log.debug("Granting service ticket for {}", request.getService());
+ log.debug("{} Granting service ticket for {}", getLogPrefix(), request.getService());
final TicketState state = new TicketState(
session.getId(),
getPrincipalName(profileRequestContext),
authnResult.getAuthenticationInstant(),
authnResult.getAuthenticationFlowId());
ticket = ticketServiceEx.createServiceTicket(
- securityConfiguration.getIdGenerator().generateIdentifier(),
- Instant.now().plus(config.getTicketValidityPeriod(profileRequestContext)),
+ securityConfig.getIdGenerator().generateIdentifier(),
+ Instant.now().plus(loginConfig.getTicketValidityPeriod(profileRequestContext)),
request.getService(),
state,
request.isRenew());
} catch (final RuntimeException e) {
- log.error("Failed granting service ticket due to error.", e);
- return ProtocolError.TicketCreationError.event(this);
+ log.error("{} Failed granting service ticket due to error.", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketCreationError.event(this));
+ return;
}
- log.info("Granted service ticket for {}", request.getService());
+
final ServiceTicketResponse response = new ServiceTicketResponse(request.getService(), ticket.getId());
if (request.isSAML()) {
response.setSaml(true);
}
- setCASResponse(profileRequestContext, response);
- return null;
+
+ try {
+ setCASResponse(profileRequestContext, response);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return;
+ }
+
+ log.info("{} Granted service ticket for {}", getLogPrefix(), request.getService());
}
/**
* Get the IdP session.
*
- * @param prc profile request context.
+ * @param prc profile request context
+ *
* @return IdP session
*/
- @Nonnull
- private IdPSession getIdPSession(final ProfileRequestContext prc) {
+ @Nullable private IdPSession getIdPSession(final ProfileRequestContext prc) {
final SessionContext sessionContext = sessionContextFunction.apply(prc);
- if (sessionContext == null || sessionContext.getIdPSession() == null) {
- throw new IllegalStateException("Cannot locate IdP session");
- }
- return sessionContext.getIdPSession();
+ return sessionContext != null ? sessionContext.getIdPSession() : null;
}
/**
@@ -164,8 +215,7 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
* @param prc profile request context.
* @return Principal name.
*/
- @Nonnull
- private String getPrincipalName(final ProfileRequestContext prc) {
+ @Nonnull private String getPrincipalName(final ProfileRequestContext prc) {
final String principal = principalLookupFunction.apply(prc);
if (principal == null ) {
throw new IllegalStateException("Cannot determine IdP subject principal name.");
@@ -176,22 +226,20 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
/**
* Gets the most recent authentication result from the IdP session.
*
- * @param session IdP session to ask for authentication results.
- *
* @return Latest authentication result.
*
* @throws IllegalStateException If no authentication results are found.
*/
- private AuthenticationResult getLatestAuthenticationResult(final IdPSession session) {
+ @Nullable private AuthenticationResult getLatestAuthenticationResult() {
AuthenticationResult latest = null;
+
for (final AuthenticationResult result : session.getAuthenticationResults()) {
if (latest == null || result.getAuthenticationInstant().isAfter(latest.getAuthenticationInstant())) {
latest = result;
}
}
- if (latest == null) {
- throw new IllegalStateException("Cannot find authentication results in IdP session");
- }
+
return latest;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeLoginAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeLoginAction.java
index 2d0e96b..8d3aa1b 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeLoginAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeLoginAction.java
@@ -24,6 +24,9 @@ import net.shibboleth.idp.cas.protocol.ProtocolParam;
import net.shibboleth.idp.cas.protocol.SamlParam;
import net.shibboleth.idp.cas.protocol.ServiceTicketRequest;
import net.shibboleth.idp.cas.protocol.ServiceTicketResponse;
+import net.shibboleth.idp.profile.ActionSupport;
+
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.springframework.webflow.core.collection.ParameterMap;
import org.springframework.webflow.execution.Event;
@@ -40,11 +43,9 @@ import org.springframework.webflow.execution.RequestContext;
*/
public class InitializeLoginAction extends AbstractCASProtocolAction<ServiceTicketRequest, ServiceTicketResponse> {
- @Nonnull
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ @Nonnull protected Event doExecute(@Nonnull final RequestContext springRequestContext,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
final ParameterMap params = springRequestContext.getRequestParameters();
String service = params.get(ProtocolParam.Service.id());
@@ -76,8 +77,12 @@ public class InitializeLoginAction extends AbstractCASProtocolAction<ServiceTick
serviceTicketRequest.setMethod(method);
}
- setCASRequest(profileRequestContext, serviceTicketRequest);
+ try {
+ setCASRequest(profileRequestContext, serviceTicketRequest);
+ } catch (final EventException e) {
+ return ActionSupport.buildEvent(this, e.getEventID());
+ }
- return null;
+ return ActionSupport.buildProceedEvent(this);
}
}
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeProxyAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeProxyAction.java
index 8925942..3c65d1c 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeProxyAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeProxyAction.java
@@ -26,7 +26,10 @@ import net.shibboleth.idp.cas.protocol.ProxyTicketResponse;
import net.shibboleth.idp.cas.ticket.ProxyGrantingTicket;
import net.shibboleth.idp.cas.ticket.TicketContext;
import net.shibboleth.idp.cas.ticket.TicketServiceEx;
+import net.shibboleth.idp.profile.ActionSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
+
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,12 +58,10 @@ import org.springframework.webflow.execution.RequestContext;
public class InitializeProxyAction extends AbstractCASProtocolAction<ProxyTicketRequest, ProxyTicketResponse> {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(InitializeProxyAction.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(InitializeProxyAction.class);
/** Manages CAS tickets. */
- @Nonnull
- private final TicketServiceEx ticketServiceEx;
-
+ @Nonnull private final TicketServiceEx ticketServiceEx;
/**
* Constructor.
@@ -71,12 +72,10 @@ public class InitializeProxyAction extends AbstractCASProtocolAction<ProxyTicket
ticketServiceEx = Constraint.isNotNull(ticketService, "Ticket service cannot be null.");
}
- @Nonnull
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
-
+ @Nonnull protected Event doExecute(@Nonnull final RequestContext springRequestContext,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
+
final ParameterMap params = springRequestContext.getRequestParameters();
String service = params.get(ProtocolParam.TargetService.id());
Event result = null;
@@ -90,20 +89,27 @@ public class InitializeProxyAction extends AbstractCASProtocolAction<ProxyTicket
result = ProtocolError.TicketNotSpecified.event(this);
}
final ProxyTicketRequest proxyTicketRequest = new ProxyTicketRequest(ticket, service);
- setCASRequest(profileRequestContext, proxyTicketRequest);
+ try {
+ setCASRequest(profileRequestContext, proxyTicketRequest);
+ } catch (final EventException e) {
+ return ActionSupport.buildEvent(this, e.getEventID());
+ }
+
if (result == null) {
try {
- log.debug("Fetching proxy-granting ticket {}", proxyTicketRequest.getPgt());
+ log.debug("{} Fetching proxy-granting ticket {}", getLogPrefix(), proxyTicketRequest.getPgt());
final ProxyGrantingTicket pgt = ticketServiceEx.fetchProxyGrantingTicket(proxyTicketRequest.getPgt());
if (pgt == null) {
return ProtocolError.TicketExpired.event(this);
}
setCASTicket(profileRequestContext, pgt);
- } catch (final RuntimeException e) {
- log.error("Failed looking up " + proxyTicketRequest.getPgt(), e);
+ } catch (final Exception e) {
+ log.error("{} Failed looking up {}", getLogPrefix(), proxyTicketRequest.getPgt(), e);
return ProtocolError.TicketRetrievalError.event(this);
}
}
+
return result;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeValidateAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeValidateAction.java
index 75f0590..4d73730 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeValidateAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/InitializeValidateAction.java
@@ -23,6 +23,9 @@ import net.shibboleth.idp.cas.protocol.ProtocolError;
import net.shibboleth.idp.cas.protocol.ProtocolParam;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
+import net.shibboleth.idp.profile.ActionSupport;
+
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.springframework.webflow.core.collection.ParameterMap;
import org.springframework.webflow.execution.Event;
@@ -41,11 +44,10 @@ import org.springframework.webflow.execution.RequestContext;
*/
public class InitializeValidateAction extends
AbstractCASProtocolAction<TicketValidationRequest, TicketValidationResponse> {
- @Nonnull
+
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ @Nonnull protected Event doExecute(@Nonnull final RequestContext springRequestContext,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
final ParameterMap params = springRequestContext.getRequestParameters();
String service = params.get(ProtocolParam.Service.id());
@@ -67,8 +69,13 @@ public class InitializeValidateAction extends
}
ticketValidationRequest.setPgtUrl(params.get(ProtocolParam.PgtUrl.id()));
- setCASRequest(profileRequestContext, ticketValidationRequest);
+ try {
+ setCASRequest(profileRequestContext, ticketValidationRequest);
+ } catch (final EventException e) {
+ return ActionSupport.buildEvent(this, e.getEventID());
+ }
return result;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PopulateProtocolErrorAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PopulateProtocolErrorAction.java
index 1fed84c..ec9c4ef 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PopulateProtocolErrorAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PopulateProtocolErrorAction.java
@@ -19,7 +19,11 @@ package net.shibboleth.idp.cas.flow.impl;
import javax.annotation.Nonnull;
+import org.opensaml.profile.action.EventException;
+import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
@@ -29,6 +33,7 @@ import net.shibboleth.idp.cas.protocol.ProxyTicketRequest;
import net.shibboleth.idp.cas.protocol.ProxyTicketResponse;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
+import net.shibboleth.idp.profile.ActionSupport;
/**
* Populates error information needed for protocol error messages.
@@ -37,20 +42,30 @@ import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
*/
public class PopulateProtocolErrorAction extends AbstractCASProtocolAction {
- @Nonnull
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateProtocolErrorAction.class);
+
@Override
- protected Event doExecute(
- @Nonnull final RequestContext springRequestContext,
+ @Nonnull protected Event doExecute(@Nonnull final RequestContext springRequestContext,
@Nonnull final ProfileRequestContext profileRequestContext) {
- final Object request = getCASRequest(profileRequestContext);
+
+ final Object request;
+ try {
+ request = getCASRequest(profileRequestContext);
+ } catch (final EventException e) {
+ return ActionSupport.buildEvent(this, e.getEventID());
+ }
+
final AbstractProtocolResponse response;
if (request instanceof ProxyTicketRequest) {
response = new ProxyTicketResponse();
} else if (request instanceof TicketValidationRequest) {
response = new TicketValidationResponse();
} else {
- throw new IllegalArgumentException("Invalid request type: " + request);
+ log.error("{} Invalid request type: {}", getLogPrefix(), request);
+ return ActionSupport.buildEvent(this, EventIds.INVALID_MESSAGE);
}
+
String code = (String) springRequestContext.getCurrentEvent().getAttributes().get("code");
String detail = (String) springRequestContext.getCurrentEvent().getAttributes().get("detailCode");
if (code == null) {
@@ -59,9 +74,16 @@ public class PopulateProtocolErrorAction extends AbstractCASProtocolAction {
if (detail == null) {
detail = ProtocolError.IllegalState.getDetailCode();
}
+
response.setErrorCode(code);
response.setErrorDetail(detail);
- setCASResponse(profileRequestContext, response);
- return null;
+ try {
+ setCASResponse(profileRequestContext, response);
+ } catch (final EventException e) {
+ return ActionSupport.buildEvent(this, e.getEventID());
+ }
+
+ return ActionSupport.buildProceedEvent(this);
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PrepareTicketValidationResponseAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PrepareTicketValidationResponseAction.java
index 387b096..56fe23f 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PrepareTicketValidationResponseAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PrepareTicketValidationResponseAction.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.function.Function;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.attribute.AttributeEncodingException;
import net.shibboleth.idp.attribute.IdPAttribute;
@@ -55,6 +56,7 @@ import net.shibboleth.utilities.java.support.service.ServiceableComponent;
import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -91,6 +93,15 @@ public class PrepareTicketValidationResponseAction extends
/** Fallback rule that does a simple/default encode. */
@NonnullAfterInit private TranscodingRule defaultTranscodingRule;
+
+ /** Stored off context from request. */
+ @Nullable private AttributeContext attributeContext;
+
+ /** Profile configuration. */
+ @Nullable private ValidateConfiguration validateConfiguration;
+
+ /** CAS response. */
+ @Nullable private TicketValidationResponse response;
/** Constructor. */
public PrepareTicketValidationResponseAction() {
@@ -127,42 +138,60 @@ public class PrepareTicketValidationResponseAction extends
Collections.singletonMap(AttributeTranscoderRegistry.PROP_TRANSCODER, transcoder));
}
- /** {@inheritDoc} */
- // CheckStyle: CyclomaticComplexity OFF
@Override
- protected void doExecute(final @Nonnull ProfileRequestContext profileRequestContext) {
-
- final AttributeContext ac = attributeContextFunction.apply(profileRequestContext);
- if (ac == null) {
- throw new IllegalStateException("AttributeContext not found in profile request context.");
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
}
-
- final ValidateConfiguration validateConfiguration = configLookupFunction.apply(profileRequestContext);
+
+ attributeContext = attributeContextFunction.apply(profileRequestContext);
+ if (attributeContext == null) {
+ log.warn("{} AttributeContext not found in profile request context", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_ATTRIBUTE_CTX);
+ return false;
+ }
+
+ validateConfiguration = configLookupFunction.apply(profileRequestContext);
if (validateConfiguration == null) {
- throw new IllegalArgumentException("Cannot locate ValidateConfiguration");
+ log.warn("{} Cannot locate ValidateConfiguration", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return false;
+ }
+
+ try {
+ response = getCASResponse(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
}
+
+ return true;
+ }
+
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
final String principal;
final String userAttributeName = validateConfiguration.getUserAttribute(profileRequestContext);
if (userAttributeName != null) {
- log.debug("Using {} for CAS username", userAttributeName);
- final IdPAttribute attribute = ac.getIdPAttributes().get(userAttributeName);
+ log.debug("{} Using {} for CAS username", getLogPrefix(), userAttributeName);
+ final IdPAttribute attribute = attributeContext.getIdPAttributes().get(userAttributeName);
if (attribute != null && !attribute.getValues().isEmpty()) {
final IdPAttributeValue value = attribute.getValues().get(0);
if (value instanceof ScopedStringAttributeValue) {
final ScopedStringAttributeValue scopedValue = (ScopedStringAttributeValue) value;
- log.warn("Lossy use of attribute value {} from attribute {}",
+ log.warn("{} Lossy use of attribute value {} from attribute {}", getLogPrefix(),
scopedValue.getValue(), attribute.getId());
principal = scopedValue.getValue();
} else if (value instanceof StringAttributeValue) {
principal = ((StringAttributeValue) value).getValue();
} else {
- log.warn("Use of attribute value type {} from attribute {}",
+ log.warn("{} Use of attribute value type {} from attribute {}", getLogPrefix(),
value.getClass(), attribute.getId());
principal = value.getNativeValue().toString();
}
} else {
- log.debug("Filtered attribute {} has no value", userAttributeName);
+ log.debug("{} Filtered attribute {} has no value", getLogPrefix(), userAttributeName);
principal = null;
}
} else {
@@ -173,10 +202,9 @@ public class PrepareTicketValidationResponseAction extends
throw new IllegalStateException("Principal cannot be null");
}
- final TicketValidationResponse response = getCASResponse(profileRequestContext);
response.setUserName(principal);
- final Collection<IdPAttribute> inputAttributes = ac.getIdPAttributes().values();
+ final Collection<IdPAttribute> inputAttributes = attributeContext.getIdPAttributes().values();
final ArrayList<Attribute> encodedAttributes = new ArrayList<>(inputAttributes.size());
ServiceableComponent<AttributeTranscoderRegistry> component = null;
@@ -198,7 +226,6 @@ public class PrepareTicketValidationResponseAction extends
encodedAttributes.forEach(a -> response.addAttribute(a));
}
- // CheckStyle: CyclomaticComplexity ON
/**
* Access the registry of transcoding rules to transform the input attribute into a target type.
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ProcessSamlMessageAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ProcessSamlMessageAction.java
index 34f2d91..80da408 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ProcessSamlMessageAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ProcessSamlMessageAction.java
@@ -25,7 +25,10 @@ import net.shibboleth.idp.cas.protocol.ProtocolParam;
import net.shibboleth.idp.cas.protocol.SamlParam;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
+import net.shibboleth.idp.profile.ActionSupport;
+
import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.common.SAMLObject;
import org.opensaml.saml.saml1.core.AssertionArtifact;
@@ -52,14 +55,11 @@ public class ProcessSamlMessageAction extends
AbstractCASProtocolAction<TicketValidationRequest, TicketValidationResponse> {
/** Class logger. */
- @Nonnull
- private final Logger log = LoggerFactory.getLogger(ProcessSamlMessageAction.class);
-
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ProcessSamlMessageAction.class);
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ @Nonnull protected Event doExecute(@Nonnull final RequestContext springRequestContext,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
profileRequestContext.setProfileId(ValidateConfiguration.PROFILE_ID);
@@ -79,7 +79,7 @@ public class ProcessSamlMessageAction extends
break;
}
} else {
- log.info("Unexpected SAMLObject type {}", msgContext.getMessage().getClass().getName());
+ log.warn("{} Unexpected SAMLObject type {}", getLogPrefix(), msgContext.getMessage().getClass().getName());
return ProtocolError.ProtocolViolation.event(this);
}
if (ticket == null) {
@@ -92,8 +92,13 @@ public class ProcessSamlMessageAction extends
ticketValidationRequest.setRenew(true);
}
- setCASRequest(profileRequestContext, ticketValidationRequest);
+ try {
+ setCASRequest(profileRequestContext, ticketValidationRequest);
+ } catch (final EventException e) {
+ return ActionSupport.buildEvent(this, e.getEventID());
+ }
- return null;
+ return ActionSupport.buildProceedEvent(this);
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PublishProtocolMessageAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PublishProtocolMessageAction.java
index d0aabe5..6bc18e3 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PublishProtocolMessageAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/PublishProtocolMessageAction.java
@@ -19,10 +19,13 @@ package net.shibboleth.idp.cas.flow.impl;
import javax.annotation.Nonnull;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
+import net.shibboleth.idp.profile.ActionSupport;
+
/**
* Action to publish the CAS protocol request or response messages, i.e.
* {@link net.shibboleth.idp.cas.protocol.ProtocolContext#getResponse()}, in Spring Webflow
@@ -47,19 +50,26 @@ public class PublishProtocolMessageAction extends AbstractCASProtocolAction {
}
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ @Nonnull protected Event doExecute(@Nonnull final RequestContext springRequestContext,
+ @Nonnull final ProfileRequestContext profileRequestContext) {
final Object message;
- if (requestFlag) {
- message = getCASRequest(profileRequestContext);
- } else {
- message = getCASResponse(profileRequestContext);
+
+ try {
+ if (requestFlag) {
+ message = getCASRequest(profileRequestContext);
+ } else {
+ message = getCASResponse(profileRequestContext);
+ }
+ } catch (final EventException e) {
+ return ActionSupport.buildEvent(this, e.getEventID());
}
+
final String className = message.getClass().getSimpleName();
final String keyName = className.substring(0, 1).toLowerCase() + className.substring(1);
springRequestContext.getFlowScope().put(keyName, message);
- return null;
+
+ return ActionSupport.buildProceedEvent(this);
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/UpdateIdPSessionWithSPSessionAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/UpdateIdPSessionWithSPSessionAction.java
index 5cb3b4c..6319e17 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/UpdateIdPSessionWithSPSessionAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/UpdateIdPSessionWithSPSessionAction.java
@@ -21,6 +21,7 @@ import java.time.Duration;
import java.time.Instant;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.cas.service.Service;
import net.shibboleth.idp.cas.session.impl.CASSPSession;
@@ -34,14 +35,14 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
- * Conditionally updates the {@link net.shibboleth.idp.session.IdPSession} with a {@link CASSPSession} to support SLO.
+ * Conditionally updates the {@link IdPSession} with a {@link CASSPSession} to support SLO.
* If the service granted access to indicates participation in SLO via {@link Service#singleLogoutParticipant},
* then a {@link CASSPSession} is created to track the SP session in order that it may receive SLO messages upon
* a request to the CAS <code>/logout</code> URI.
@@ -59,35 +60,54 @@ public class UpdateIdPSessionWithSPSessionAction extends AbstractCASProtocolActi
/** Lifetime of sessions to create. */
@Nonnull private final Duration sessionLifetime;
+ /** Ticket. */
+ @Nullable private Ticket ticket;
+
+ /** CAS service. */
+ @Nullable private Service service;
/**
- * Creates a new instance with given parameters.
+ * Constructor.
*
* @param resolver Session resolver component
* @param lifetime determines upper bound for expiration of the {@link CASSPSession} to be created
*/
public UpdateIdPSessionWithSPSessionAction(@Nonnull final SessionResolver resolver,
@Nonnull final Duration lifetime) {
- sessionResolver = Constraint.isNotNull(resolver, "Session resolver cannot be null.");
+ sessionResolver = Constraint.isNotNull(resolver, "Session resolver cannot be null");
sessionLifetime = Constraint.isNotNull(lifetime, "Lifetime cannot be null");
}
- /** {@inheritDoc} */
@Override
- @Nonnull protected Event doExecute(final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
- final Ticket ticket = getCASTicket(profileRequestContext);
- final Service service = getCASService(profileRequestContext);
- if (!service.isSingleLogoutParticipant()) {
- return null;
+ try {
+ service = getCASService(profileRequestContext);
+ if (!service.isSingleLogoutParticipant()) {
+ return false;
+ }
+
+ ticket = getCASTicket(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
}
+
+ return true;
+ }
+
+ @Override
+ @Nonnull protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
IdPSession session = null;
try {
- log.debug("Attempting to retrieve session {}", ticket.getSessionId());
+ log.debug("{} Attempting to retrieve session {}", getLogPrefix(), ticket.getSessionId());
session = sessionResolver.resolveSingle(new CriteriaSet(new SessionIdCriterion(ticket.getSessionId())));
} catch (final ResolverException e) {
- log.warn("Possible sign of misconfiguration, IdPSession resolution error: {}", e);
+ log.warn("{} Possible sign of misconfiguration, IdPSession resolution error: {}", getLogPrefix(), e);
}
if (session != null) {
final Instant now = Instant.now();
@@ -96,15 +116,15 @@ public class UpdateIdPSessionWithSPSessionAction extends AbstractCASProtocolActi
now,
now.plus(sessionLifetime),
ticket.getId());
- log.debug("Created SP session {}", sps);
+ log.debug("{} Created SP session {}", getLogPrefix(), sps);
try {
session.addSPSession(sps);
} catch (final SessionException e) {
- log.warn("Failed updating IdPSession with CASSPSession", e);
+ log.warn("{} Failed updating IdPSession with CASSPSession", getLogPrefix(), e);
}
} else {
- log.info("Cannot store CASSPSession since IdPSession not found");
+ log.info("{} Cannot store CASSPSession since IdPSession not found", getLogPrefix());
}
- return null;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
index 66b2b03..61babc6 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
@@ -22,13 +22,15 @@ import java.net.URISyntaxException;
import java.time.Instant;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.apache.http.client.utils.URIBuilder;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
+import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
import net.shibboleth.idp.cas.config.impl.ConfigLookupFunction;
import net.shibboleth.idp.cas.config.impl.ValidateConfiguration;
@@ -42,6 +44,7 @@ import net.shibboleth.idp.cas.ticket.ProxyTicket;
import net.shibboleth.idp.cas.ticket.ServiceTicket;
import net.shibboleth.idp.cas.ticket.Ticket;
import net.shibboleth.idp.cas.ticket.TicketServiceEx;
+import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.profile.config.SecurityConfiguration;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.security.IdentifierGenerationStrategy;
@@ -74,48 +77,71 @@ public class ValidateProxyCallbackAction
/** Manages CAS tickets. */
@Nonnull private final TicketServiceEx ticketServiceEx;
+ /** Profile config. */
+ @Nullable private ValidateConfiguration validateConfig;
+
+ /** Security config. */
+ @Nullable private SecurityConfiguration securityConfig;
+
+ /** CAS ticket. */
+ @Nullable private Ticket ticket;
+ /** CAS request. */
+ @Nullable private TicketValidationRequest request;
+
+ /** CAS response. */
+ @Nullable private TicketValidationResponse response;
+
/**
- * Creates a new instance.
+ * Constructor.
*
* @param validator Component that validates the proxy callback endpoint.
* @param ticketService Ticket service component.
*/
- public ValidateProxyCallbackAction(
- @Nonnull final ProxyValidator validator,
+ public ValidateProxyCallbackAction(@Nonnull final ProxyValidator validator,
@Nonnull final TicketServiceEx ticketService) {
proxyValidator = Constraint.isNotNull(validator, "ProxyValidator cannot be null");
ticketServiceEx = Constraint.isNotNull(ticketService, "TicketService cannot be null");
configLookupFunction = new ConfigLookupFunction<>(ValidateConfiguration.class);
}
-
+
@Override
- @Nonnull
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
-
- final TicketValidationRequest request = getCASRequest(profileRequestContext);
- final TicketValidationResponse response = getCASResponse(profileRequestContext);
- final Ticket ticket = getCASTicket(profileRequestContext);
- final ValidateConfiguration config = configLookupFunction.apply(profileRequestContext);
- if (config == null) {
- throw new IllegalStateException("Proxy-granting ticket configuration undefined");
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ validateConfig = configLookupFunction.apply(profileRequestContext);
+ if (validateConfig == null) {
+ ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
+ return false;
}
- final SecurityConfiguration securityConfiguration = config.getSecurityConfiguration(profileRequestContext);
- if (securityConfiguration == null || securityConfiguration.getIdGenerator() == null) {
- throw new IllegalStateException(
- "Invalid proxy-granting ticket configuration: SecurityConfiguration#idGenerator undefined");
+ securityConfig = validateConfig.getSecurityConfiguration(profileRequestContext);
+ if (securityConfig == null) {
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_SEC_CFG);
+ return false;
}
- final IdentifierGenerationStrategy pgtGenerator = config.getPGTIOUGenerator(profileRequestContext);
- if (pgtGenerator == null) {
- throw new IllegalStateException("Invalid proxy-granting ticket configuration: PGTIOUGenerator undefined");
+ try {
+ ticket = getCASTicket(profileRequestContext);
+ request = getCASRequest(profileRequestContext);
+ response = getCASResponse(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
}
+
+ return true;
+ }
+
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ final IdentifierGenerationStrategy pgtGenerator = validateConfig.getPGTIOUGenerator(profileRequestContext);
final ProxyIdentifiers proxyIds = new ProxyIdentifiers(
- securityConfiguration.getIdGenerator().generateIdentifier(),
+ securityConfig.getIdGenerator().generateIdentifier(),
pgtGenerator.generateIdentifier());
final URI proxyCallbackUri;
try {
@@ -124,12 +150,16 @@ public class ValidateProxyCallbackAction
.addParameter(ProtocolParam.PgtIou.id(), proxyIds.getPgtIou())
.build();
} catch (final URISyntaxException e) {
- throw new RuntimeException("Error creating proxy callback URL", e);
+ log.warn("{} Error creating proxy callback URL", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.RUNTIME_EXCEPTION);
+ return;
}
+
try {
- log.debug("Attempting proxy authentication to {}", proxyCallbackUri);
+ log.debug("{} Attempting proxy authentication to {}", getLogPrefix(), proxyCallbackUri);
proxyValidator.validate(profileRequestContext, proxyCallbackUri);
- final Instant expiration = Instant.now().plus(config.getTicketValidityPeriod(profileRequestContext));
+ final Instant expiration =
+ Instant.now().plus(validateConfig.getTicketValidityPeriod(profileRequestContext));
if (ticket instanceof ServiceTicket) {
ticketServiceEx.createProxyGrantingTicket(proxyIds.getPgtId(), expiration, (ServiceTicket) ticket);
} else {
@@ -137,9 +167,10 @@ public class ValidateProxyCallbackAction
}
response.setPgtIou(proxyIds.getPgtIou());
} catch (final Exception e) {
- log.info("Proxy authentication failed for " + request.getPgtUrl() + ": " + e);
- return ProtocolError.ProxyCallbackAuthenticationFailure.event(this);
+ log.warn("{} Proxy authentication failed for {}", getLogPrefix(), request.getPgtUrl(), e);
+ ActionSupport.buildEvent(profileRequestContext,
+ ProtocolError.ProxyCallbackAuthenticationFailure.event(this));
}
- return null;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateRenewAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateRenewAction.java
index 1f80e46..6403817 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateRenewAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateRenewAction.java
@@ -18,17 +18,19 @@
package net.shibboleth.idp.cas.flow.impl;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.cas.protocol.ProtocolError;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
import net.shibboleth.idp.cas.ticket.ServiceTicket;
import net.shibboleth.idp.cas.ticket.Ticket;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* Ensures that a service ticket validation request that specifies renew=true matches the renew flag on the ticket
@@ -44,28 +46,48 @@ import org.springframework.webflow.execution.RequestContext;
public class ValidateRenewAction extends AbstractCASProtocolAction<TicketValidationRequest, TicketValidationResponse> {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(ValidateRenewAction.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ValidateRenewAction.class);
+
+ /** CAS ticket. */
+ @Nullable private Ticket ticket;
+ /** CAS request. */
+ @Nullable private TicketValidationRequest request;
+
+ @Override
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ try {
+ ticket = getCASTicket(profileRequestContext);
+ request = getCASRequest(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
- @Nonnull
+ return true;
+ }
+
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- final TicketValidationRequest request = getCASRequest(profileRequestContext);
- final Ticket ticket = getCASTicket(profileRequestContext);
if (ticket instanceof ServiceTicket) {
if (request.isRenew() != ((ServiceTicket) ticket).isRenew()) {
- log.debug("Renew=true requested at validation time but ticket not issued with renew=true.");
- return ProtocolError.TicketNotFromRenew.event(this);
+ log.debug("{} Renew=true requested at validation time but ticket not issued with renew=true",
+ getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketNotFromRenew.event(this));
+ return;
}
} else {
// Proxy ticket validation
if (request.isRenew()) {
- return ProtocolError.RenewIncompatibleWithProxy.event(this);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.RenewIncompatibleWithProxy.event(this));
+ return;
}
}
- return null;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateTicketAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateTicketAction.java
index 74691c0..d54a48d 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateTicketAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateTicketAction.java
@@ -20,6 +20,7 @@ package net.shibboleth.idp.cas.flow.impl;
import java.time.Instant;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import net.shibboleth.idp.cas.config.impl.ConfigLookupFunction;
import net.shibboleth.idp.cas.config.impl.LoginConfiguration;
@@ -31,12 +32,14 @@ import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
import net.shibboleth.idp.cas.ticket.ProxyTicket;
import net.shibboleth.idp.cas.ticket.Ticket;
import net.shibboleth.idp.cas.ticket.TicketServiceEx;
+import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.utilities.java.support.logic.Constraint;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* CAS protocol service ticket validation action. Emits one of the following events based on validation result:
@@ -55,39 +58,55 @@ import org.springframework.webflow.execution.RequestContext;
public class ValidateTicketAction extends AbstractCASProtocolAction<TicketValidationRequest, TicketValidationResponse> {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(ValidateTicketAction.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ValidateTicketAction.class);
/** Profile configuration lookup function. */
- private final ConfigLookupFunction<ValidateConfiguration> configLookupFunction =
- new ConfigLookupFunction<>(ValidateConfiguration.class);
+ @Nonnull private final ConfigLookupFunction<ValidateConfiguration> configLookupFunction;
/** Manages CAS tickets. */
- @Nonnull
- private final TicketServiceEx ticketServiceEx;
+ @Nonnull private final TicketServiceEx ticketServiceEx;
+ /** Profile config. */
+ @Nullable private ValidateConfiguration validateConfig;
+ /** CAS request. */
+ @Nullable private TicketValidationRequest request;
+
/**
- * Creates a new instance.
+ * Constructor.
*
- * @param ticketService Ticket service component.
+ * @param ticketService ticket service component
*/
public ValidateTicketAction(@Nonnull final TicketServiceEx ticketService) {
ticketServiceEx = Constraint.isNotNull(ticketService, "TicketService cannot be null");
+ configLookupFunction = new ConfigLookupFunction<>(ValidateConfiguration.class);
}
- @Nonnull
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
-
- final ValidateConfiguration config = configLookupFunction.apply(profileRequestContext);
- if (config == null) {
- log.warn("Ticket validation configuration undefined");
- return ProtocolError.IllegalState.event(this);
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
+
+ validateConfig = configLookupFunction.apply(profileRequestContext);
+ if (validateConfig == null) {
+ ActionSupport.buildEvent(profileRequestContext,IdPEventIds.INVALID_PROFILE_CONFIG);
+ return false;
}
+
+ try {
+ request = getCASRequest(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- final TicketValidationRequest request = getCASRequest(profileRequestContext);
final Ticket ticket;
try {
final String ticketId = request.getTicket();
@@ -97,32 +116,48 @@ public class ValidateTicketAction extends AbstractCASProtocolAction<TicketValida
} else if (ticketId.startsWith(ProxyConfiguration.DEFAULT_TICKET_PREFIX)) {
ticket = ticketServiceEx.removeProxyTicket(ticketId);
} else {
- return ProtocolError.InvalidTicketFormat.event(this);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.InvalidTicketFormat.event(this));
+ return;
}
if (ticket != null) {
- log.debug("Found and removed {}/{} from ticket store", ticket, ticket.getSessionId());
+ log.debug("{} Found and removed {}/{} from ticket store", getLogPrefix(), ticket,
+ ticket.getSessionId());
}
} catch (final RuntimeException e) {
- log.debug("CAS ticket retrieval failed with error: {}", e);
- return ProtocolError.TicketRetrievalError.event(this);
+ log.debug("{} CAS ticket retrieval failed with error: {}", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketRetrievalError.event(this));
+ return;
}
if (ticket == null || ticket.getExpirationInstant().isBefore(Instant.now())) {
- return ProtocolError.TicketExpired.event(this);
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketExpired.event(this));
+ return;
}
- if (config.getServiceComparator(profileRequestContext).compare(
+ if (validateConfig.getServiceComparator(profileRequestContext).compare(
ticket.getService(), request.getService()) != 0) {
- log.debug("Service issued for {} does not match {}", ticket.getService(), request.getService());
- return ProtocolError.ServiceMismatch.event(this);
+ log.debug("{} Service issued for {} does not match {}", getLogPrefix(), ticket.getService(),
+ request.getService());
+ ActionSupport.buildEvent(profileRequestContext, ProtocolError.ServiceMismatch.event(this));
+ return;
+ }
+
+ try {
+ setCASResponse(profileRequestContext, new TicketValidationResponse());
+ setCASTicket(profileRequestContext, ticket);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return;
}
- log.info("Successfully validated {} for {}", request.getTicket(), request.getService());
- setCASResponse(profileRequestContext, new TicketValidationResponse());
- setCASTicket(profileRequestContext, ticket);
+ log.info("{} Successfully validated {} for {}", getLogPrefix(), request.getTicket(), request.getService());
+
if (ticket instanceof ProxyTicket) {
- return Events.ProxyTicketValidated.event(this);
+ ActionSupport.buildEvent(profileRequestContext, Events.ProxyTicketValidated.event(this));
+ return;
}
- return Events.ServiceTicketValidated.event(this);
+
+ ActionSupport.buildEvent(profileRequestContext, Events.ServiceTicketValidated.event(this));
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/WriteValidateResponseAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/WriteValidateResponseAction.java
index fad8d09..98c75e5 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/WriteValidateResponseAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/WriteValidateResponseAction.java
@@ -20,13 +20,15 @@ package net.shibboleth.idp.cas.flow.impl;
import java.io.IOException;
import java.io.PrintWriter;
import javax.annotation.Nonnull;
-import javax.servlet.http.HttpServletResponse;
+import javax.annotation.Nullable;
import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventException;
import org.opensaml.profile.context.ProfileRequestContext;
-import org.springframework.webflow.execution.Event;
-import org.springframework.webflow.execution.RequestContext;
/**
* CAS 1.0 protocol response handler.
@@ -36,12 +38,16 @@ import org.springframework.webflow.execution.RequestContext;
*/
public class WriteValidateResponseAction extends
AbstractCASProtocolAction<TicketValidationRequest, TicketValidationResponse> {
+
/** CAS 1.0 protocol content type is plain text. */
- private static final String CONTENT_TYPE = "text/plain;charset=utf-8";
+ @Nonnull @NotEmpty private static final String CONTENT_TYPE = "text/plain;charset=utf-8";
/** Protocol success flag indicates what kind of response to provide. */
private final boolean success;
+ /** CAS response. */
+ @Nullable private TicketValidationResponse response;
+
/**
* Constructor.
*
@@ -52,16 +58,27 @@ public class WriteValidateResponseAction extends
}
@Override
- protected Event doExecute(
- final @Nonnull RequestContext springRequestContext,
- final @Nonnull ProfileRequestContext profileRequestContext) {
+ protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ }
- final TicketValidationResponse response = getCASResponse(profileRequestContext);
try {
- final HttpServletResponse servletResponse =
- (HttpServletResponse) springRequestContext.getExternalContext().getNativeResponse();
- servletResponse.setContentType(CONTENT_TYPE);
- final PrintWriter output = servletResponse.getWriter();
+ response = getCASResponse(profileRequestContext);
+ } catch (final EventException e) {
+ ActionSupport.buildEvent(profileRequestContext, e.getEventID());
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+ try {
+ getHttpServletResponse().setContentType(CONTENT_TYPE);
+ final PrintWriter output = getHttpServletResponse().getWriter();
if (success) {
output.print("yes\n");
output.print(response.getUserName() + '\n');
@@ -72,6 +89,6 @@ public class WriteValidateResponseAction extends
} catch (final IOException e) {
throw new RuntimeException("IO error writing CAS protocol response", e);
}
- return null;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/BuildRelyingPartyContextActionTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/BuildRelyingPartyContextActionTest.java
index c4464fa..12e81e8 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/BuildRelyingPartyContextActionTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/flow/impl/BuildRelyingPartyContextActionTest.java
@@ -28,13 +28,15 @@ import org.testng.annotations.Test;
import static org.testng.Assert.*;
+import org.opensaml.profile.action.EventException;
+
public class BuildRelyingPartyContextActionTest extends AbstractFlowActionTest {
@Autowired
private BuildRelyingPartyContextAction action;
@Test
- public void testExecuteFromServiceTicketRequest() {
+ public void testExecuteFromServiceTicketRequest() throws EventException {
final String serviceURL = "https://serviceA.example.org:8443/landing";
final RequestContext requestContext = new TestContextBuilder(LoginConfiguration.PROFILE_ID)
.addProtocolContext(new ServiceTicketRequest(serviceURL), null)
@@ -47,7 +49,7 @@ public class BuildRelyingPartyContextActionTest extends AbstractFlowActionTest {
}
@Test
- public void testExecuteFromTicketValidationRequest() {
+ public void testExecuteFromTicketValidationRequest() throws EventException {
final String serviceURL = "http://serviceB.example.org/";
final RequestContext requestContext = new TestContextBuilder(LoginConfiguration.PROFILE_ID)
.addProtocolContext(new TicketValidationRequest(serviceURL, "ST-123"), null)
@@ -60,7 +62,7 @@ public class BuildRelyingPartyContextActionTest extends AbstractFlowActionTest {
}
@Test
- public void testExecuteFromProxyTicketRequest() {
+ public void testExecuteFromProxyTicketRequest() throws EventException {
final String serviceURL = "http://mallory.untrusted.org/";
final RequestContext requestContext = new TestContextBuilder(LoginConfiguration.PROFILE_ID)
.addProtocolContext(new ProxyTicketRequest("PGT-123", serviceURL), null)
diff --git a/idp-conf/src/main/resources/system/flows/cas/cas-abstract-beans.xml b/idp-conf/src/main/resources/system/flows/cas/cas-abstract-beans.xml
index 5cca89d..ec50f98 100644
--- a/idp-conf/src/main/resources/system/flows/cas/cas-abstract-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/cas/cas-abstract-beans.xml
@@ -29,15 +29,14 @@
p:metricStrategy="#{getObject('shibboleth.metrics.MetricStrategy')}" />
<bean id="BuildRelyingPartyContext"
- class="net.shibboleth.idp.cas.flow.impl.BuildRelyingPartyContextAction"
+ class="net.shibboleth.idp.cas.flow.impl.BuildRelyingPartyContextAction" scope="prototype"
c:registries="#{getObject('shibboleth.CASServiceRegistries') ?: getObject('shibboleth.DefaultCASServiceRegistries')}" />
- <bean id="BuildSAMLMetadataContext"
+ <bean id="BuildSAMLMetadataContext" scope="prototype"
class="net.shibboleth.idp.cas.flow.impl.BuildSAMLMetadataContextAction" />
<bean id="PopulateInboundInterceptContext"
- class="net.shibboleth.idp.profile.interceptor.impl.PopulateProfileInterceptorContext"
- scope="prototype"
+ class="net.shibboleth.idp.profile.interceptor.impl.PopulateProfileInterceptorContext" scope="prototype"
p:availableFlows-ref="shibboleth.AvailableInterceptFlows">
<property name="activeFlowsLookupStrategy">
<bean class="net.shibboleth.idp.profile.config.navigate.InboundFlowsLookupFunction" />
@@ -45,8 +44,7 @@
</bean>
<bean id="PopulateOutboundInterceptContext"
- class="net.shibboleth.idp.profile.interceptor.impl.PopulateProfileInterceptorContext"
- scope="prototype"
+ class="net.shibboleth.idp.profile.interceptor.impl.PopulateProfileInterceptorContext" scope="prototype"
p:availableFlows-ref="shibboleth.AvailableInterceptFlows">
<property name="activeFlowsLookupStrategy">
<bean class="net.shibboleth.idp.profile.config.navigate.OutboundFlowsLookupFunction" />
@@ -54,37 +52,32 @@
</bean>
<bean id="PublishProtocolRequest"
- class="net.shibboleth.idp.cas.flow.impl.PublishProtocolMessageAction"
+ class="net.shibboleth.idp.cas.flow.impl.PublishProtocolMessageAction" scope="prototype"
c:isRequest="true" />
<bean id="PublishProtocolResponse"
- class="net.shibboleth.idp.cas.flow.impl.PublishProtocolMessageAction"
+ class="net.shibboleth.idp.cas.flow.impl.PublishProtocolMessageAction" scope="prototype"
c:isRequest="false" />
<bean id="SelectProfileConfiguration"
- class="net.shibboleth.idp.profile.impl.SelectProfileConfiguration"
- scope="prototype" />
+ class="net.shibboleth.idp.profile.impl.SelectProfileConfiguration" scope="prototype" />
<bean id="SelectRelyingPartyConfiguration"
- class="net.shibboleth.idp.profile.impl.SelectRelyingPartyConfiguration"
- scope="prototype"
+ class="net.shibboleth.idp.profile.impl.SelectRelyingPartyConfiguration" scope="prototype"
p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
<bean id="PopulateSubjectContext"
- class="net.shibboleth.idp.profile.impl.PopulateSubjectContext"
- scope="prototype"
+ class="net.shibboleth.idp.profile.impl.PopulateSubjectContext" scope="prototype"
p:principalNameLookupStrategy-ref="PrincipalLookupFunction" />
<bean id="ResolveAttributes"
- class="net.shibboleth.idp.profile.impl.ResolveAttributes"
- scope="prototype"
+ class="net.shibboleth.idp.profile.impl.ResolveAttributes" scope="prototype"
c:resolverService-ref="shibboleth.AttributeResolverService"
p:transcoderRegistry-ref="shibboleth.AttributeRegistryService"
p:maskFailures="%{idp.service.attribute.resolver.maskFailures:true}" />
<bean id="FilterAttributes"
- class="net.shibboleth.idp.profile.impl.FilterAttributes"
- scope="prototype"
+ class="net.shibboleth.idp.profile.impl.FilterAttributes" scope="prototype"
c:filterService-ref="shibboleth.AttributeFilterService"
p:maskFailures="%{idp.service.attribute.filter.maskFailures:true}"
p:metadataResolver-ref="shibboleth.MetadataResolver">
@@ -106,8 +99,7 @@
p:eventMap="#{getObject('shibboleth.EventViewMap')}" />
<bean id="WriteAuditLog"
- class="net.shibboleth.idp.profile.audit.impl.WriteAuditLog"
- scope="prototype"
+ class="net.shibboleth.idp.profile.audit.impl.WriteAuditLog" scope="prototype"
p:formattingMap-ref="shibboleth.AuditFormattingMap"
p:dateTimeFormat="#{getObject('shibboleth.AuditDateTimeFormat')}"
p:useDefaultTimeZone="#{getObject('shibboleth.AuditDefaultTimeZone') ?: false}"
@@ -117,5 +109,6 @@
p:fieldExtractors="#{getObject('shibboleth.ErrorViewAuditExtractors') ?: getObject('shibboleth.DefaultErrorViewAuditExtractors')}" />
<bean id="PopulateProtocolError"
- class="net.shibboleth.idp.cas.flow.impl.PopulateProtocolErrorAction" />
+ class="net.shibboleth.idp.cas.flow.impl.PopulateProtocolErrorAction" scope="prototype" />
+
</beans>
diff --git a/idp-conf/src/main/resources/system/flows/cas/login/login-beans.xml b/idp-conf/src/main/resources/system/flows/cas/login/login-beans.xml
index e778061..73ff17a 100644
--- a/idp-conf/src/main/resources/system/flows/cas/login/login-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/cas/login/login-beans.xml
@@ -10,7 +10,7 @@
<!-- Action beans -->
<bean id="InitializeProfileRequestContext"
- class="net.shibboleth.idp.profile.impl.InitializeProfileRequestContext"
+ class="net.shibboleth.idp.profile.impl.InitializeProfileRequestContext" scope="prototype"
p:profileId="#{T(net.shibboleth.idp.cas.config.impl.LoginConfiguration).PROFILE_ID}"
p:loggingId="%{idp.service.logging.cas:SSO}"
p:browserProfile="true" />
@@ -20,43 +20,39 @@
p:httpServletRequest-ref="shibboleth.HttpServletRequest" />
<bean id="PopulateClientStorageLoadContext"
- class="org.opensaml.storage.impl.client.PopulateClientStorageLoadContext"
- scope="prototype"
+ class="org.opensaml.storage.impl.client.PopulateClientStorageLoadContext" scope="prototype"
p:storageServices="#{ getObject('shibboleth.ClientStorageServices') ?: getObject('shibboleth.DefaultClientStorageServices') }" />
<bean id="PopulateClientStorageSaveContext"
- class="org.opensaml.storage.impl.client.PopulateClientStorageSaveContext"
- scope="prototype"
+ class="org.opensaml.storage.impl.client.PopulateClientStorageSaveContext" scope="prototype"
p:storageServices="#{ getObject('shibboleth.ClientStorageServices') ?: getObject('shibboleth.DefaultClientStorageServices') }" />
<bean id="InitializeLogin"
- class="net.shibboleth.idp.cas.flow.impl.InitializeLoginAction" />
+ class="net.shibboleth.idp.cas.flow.impl.InitializeLoginAction" scope="prototype"/>
<bean id="BuildAuthenticationContext"
- class="net.shibboleth.idp.cas.flow.impl.BuildAuthenticationContextAction" />
+ class="net.shibboleth.idp.cas.flow.impl.BuildAuthenticationContextAction" scope="prototype" />
<bean id="GrantServiceTicket"
- class="net.shibboleth.idp.cas.flow.impl.GrantServiceTicketAction"
+ class="net.shibboleth.idp.cas.flow.impl.GrantServiceTicketAction" scope="prototype"
c:ticketService="#{getObject('shibboleth.CASTicketService') ?: getObject('shibboleth.DefaultCASTicketService')}" />
<bean id="PopulateSessionContext"
- class="net.shibboleth.idp.session.impl.PopulateSessionContext"
- scope="prototype"
+ class="net.shibboleth.idp.session.impl.PopulateSessionContext" scope="prototype"
p:activationCondition="%{idp.session.enabled:true}"
p:httpServletRequest-ref="shibboleth.HttpServletRequest"
p:sessionResolver-ref="shibboleth.SessionManager" />
<bean id="LoginConfigLookup"
- class="net.shibboleth.idp.cas.config.impl.ConfigLookupFunction"
+ class="net.shibboleth.idp.cas.config.impl.ConfigLookupFunction" scope="prototype"
c:clazz="net.shibboleth.idp.cas.config.impl.LoginConfiguration" />
<bean id="SubjectContextLookup"
- class="org.opensaml.messaging.context.navigate.ChildContextLookup"
+ class="org.opensaml.messaging.context.navigate.ChildContextLookup" scope="prototype"
c:type="net.shibboleth.idp.authn.context.SubjectContext" />
<bean id="PopulatePostAuthnInterceptContext"
- class="net.shibboleth.idp.profile.interceptor.impl.PopulateProfileInterceptorContext"
- scope="prototype"
+ class="net.shibboleth.idp.profile.interceptor.impl.PopulateProfileInterceptorContext" scope="prototype"
p:availableFlows-ref="shibboleth.AvailableInterceptFlows">
<property name="activeFlowsLookupStrategy">
<bean class="net.shibboleth.idp.authn.config.navigate.PostAuthenticationFlowsLookupFunction" />
@@ -77,4 +73,5 @@
</constructor-arg>
<constructor-arg name="f" ref="SessionContextLookup" />
</bean>
+
</beans>
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/system/flows/cas/proxy/proxy-beans.xml b/idp-conf/src/main/resources/system/flows/cas/proxy/proxy-beans.xml
index 0cfb86a..8c7290f 100644
--- a/idp-conf/src/main/resources/system/flows/cas/proxy/proxy-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/cas/proxy/proxy-beans.xml
@@ -10,17 +10,17 @@
<!-- Action beans -->
<bean id="InitializeProfileRequestContext"
- class="net.shibboleth.idp.profile.impl.InitializeProfileRequestContext"
+ class="net.shibboleth.idp.profile.impl.InitializeProfileRequestContext" scope="prototype"
p:profileId="#{T(net.shibboleth.idp.cas.config.impl.ProxyConfiguration).PROFILE_ID}"
p:loggingId="%{idp.service.logging.cas:SSO}"
p:browserProfile="false" />
<bean id="InitializeProxy"
- class="net.shibboleth.idp.cas.flow.impl.InitializeProxyAction"
+ class="net.shibboleth.idp.cas.flow.impl.InitializeProxyAction" scope="prototype"
c:ticketService="#{getObject('shibboleth.CASTicketService') ?: getObject('shibboleth.DefaultCASTicketService')}" />
<bean id="GrantProxyTicket"
- class="net.shibboleth.idp.cas.flow.impl.GrantProxyTicketAction"
+ class="net.shibboleth.idp.cas.flow.impl.GrantProxyTicketAction" scope="prototype"
c:ticketService="#{getObject('shibboleth.CASTicketService') ?: getObject('shibboleth.DefaultCASTicketService')}"
c:resolver-ref="shibboleth.SessionManager"
p:validateIdPSessionPredicate="#{getObject('shibboleth.CASProxyValidateIdPSessionPredicate') ?: getObject('shibboleth.DefaultCASProxyValidateIdPSessionPredicate')}" />
@@ -30,4 +30,5 @@
<!-- Supplementary beans -->
<bean id="PrincipalLookupFunction" class="net.shibboleth.idp.cas.ticket.TicketPrincipalLookupFunction" />
+
</beans>
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/system/flows/cas/proxyValidate/proxyValidate-beans.xml b/idp-conf/src/main/resources/system/flows/cas/proxyValidate/proxyValidate-beans.xml
index 31e8729..2d5f04e 100644
--- a/idp-conf/src/main/resources/system/flows/cas/proxyValidate/proxyValidate-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/cas/proxyValidate/proxyValidate-beans.xml
@@ -9,7 +9,7 @@
<!-- Action beans -->
<bean id="BuildProxyChain"
- class="net.shibboleth.idp.cas.flow.impl.BuildProxyChainAction"
+ class="net.shibboleth.idp.cas.flow.impl.BuildProxyChainAction" scope="prototype"
c:ticketService="#{getObject('shibboleth.CASTicketService') ?: getObject('shibboleth.DefaultCASTicketService')}" />
</beans>
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/system/flows/cas/samlValidate/samlValidate-beans.xml b/idp-conf/src/main/resources/system/flows/cas/samlValidate/samlValidate-beans.xml
index 5caa20b..d2f0278 100644
--- a/idp-conf/src/main/resources/system/flows/cas/samlValidate/samlValidate-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/cas/samlValidate/samlValidate-beans.xml
@@ -9,41 +9,35 @@
default-init-method="initialize">
<bean id="DecodeMessage"
- class="org.opensaml.profile.action.impl.DecodeMessage"
- scope="prototype"
+ class="org.opensaml.profile.action.impl.DecodeMessage" scope="prototype"
c:messageDecoder-ref="SoapDecoder" />
<bean id="SoapDecoder"
- class="org.opensaml.saml.saml1.binding.decoding.impl.HTTPSOAP11Decoder"
- scope="prototype"
+ class="org.opensaml.saml.saml1.binding.decoding.impl.HTTPSOAP11Decoder" scope="prototype"
p:httpServletRequest-ref="shibboleth.HttpServletRequest" />
<bean id="ProcessSamlMessage"
- class="net.shibboleth.idp.cas.flow.impl.ProcessSamlMessageAction"
- scope="prototype" />
+ class="net.shibboleth.idp.cas.flow.impl.ProcessSamlMessageAction" scope="prototype" />
<bean id="BuildSamlValidationSuccessMessage"
- class="net.shibboleth.idp.cas.flow.impl.BuildSamlValidationSuccessMessageAction"
- scope="prototype"
+ class="net.shibboleth.idp.cas.flow.impl.BuildSamlValidationSuccessMessageAction" scope="prototype"
c:strategy-ref="shibboleth.DefaultIdentifierGenerationStrategy"
c:id="%{idp.entityID}"
p:outgoingBinding-ref="shibboleth.Binding.SAML1SOAP" />
<bean id="BuildSamlValidationFailureMessage"
- class="net.shibboleth.idp.cas.flow.impl.BuildSamlValidationFailureMessageAction"
- scope="prototype"
+ class="net.shibboleth.idp.cas.flow.impl.BuildSamlValidationFailureMessageAction" scope="prototype"
p:outgoingBinding-ref="shibboleth.Binding.SAML1SOAP" />
<bean id="MessageEncoderFactory"
- class="net.shibboleth.idp.saml.profile.impl.SpringAwareMessageEncoderFactory" />
+ class="net.shibboleth.idp.saml.profile.impl.SpringAwareMessageEncoderFactory" scope="prototype" />
<bean id="EncodeMessage"
- class="org.opensaml.profile.action.impl.EncodeMessage"
- scope="prototype"
+ class="org.opensaml.profile.action.impl.EncodeMessage" scope="prototype"
p:messageEncoderFactory-ref="MessageEncoderFactory"
p:messageHandler="#{getObject('shibboleth.BindingSpecificMessageHandler')}" />
<bean id="RecordResponseComplete"
- class="net.shibboleth.idp.profile.impl.RecordResponseComplete"
- scope="prototype" />
+ class="net.shibboleth.idp.profile.impl.RecordResponseComplete" scope="prototype" />
+
</beans>
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/system/flows/cas/validate-abstract-beans.xml b/idp-conf/src/main/resources/system/flows/cas/validate-abstract-beans.xml
index a4a7c62..64163b1 100644
--- a/idp-conf/src/main/resources/system/flows/cas/validate-abstract-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/cas/validate-abstract-beans.xml
@@ -10,7 +10,7 @@
<!-- Action beans -->
<bean id="InitializeProfileRequestContext"
- class="net.shibboleth.idp.profile.impl.InitializeProfileRequestContext"
+ class="net.shibboleth.idp.profile.impl.InitializeProfileRequestContext" scope="prototype"
p:profileId="#{T(net.shibboleth.idp.cas.config.impl.ValidateConfiguration).PROFILE_ID}"
p:loggingId="%{idp.service.logging.cas:SSO}"
p:browserProfile="false" />
@@ -20,29 +20,29 @@
p:metricStrategy="#{getObject('shibboleth.metrics.MetricStrategy')}" />
<bean id="InitializeValidate"
- class="net.shibboleth.idp.cas.flow.impl.InitializeValidateAction" />
+ class="net.shibboleth.idp.cas.flow.impl.InitializeValidateAction" scope="prototype" />
<bean id="ValidateTicket"
- class="net.shibboleth.idp.cas.flow.impl.ValidateTicketAction"
+ class="net.shibboleth.idp.cas.flow.impl.ValidateTicketAction" scope="prototype"
c:ticketService="#{getObject('shibboleth.CASTicketService') ?: getObject('shibboleth.DefaultCASTicketService')}" />
<bean id="ValidateRenew"
- class="net.shibboleth.idp.cas.flow.impl.ValidateRenewAction" />
+ class="net.shibboleth.idp.cas.flow.impl.ValidateRenewAction" scope="prototype" />
<bean id="CheckProxyAuthorization"
- class="net.shibboleth.idp.cas.flow.impl.CheckProxyAuthorizationAction" />
+ class="net.shibboleth.idp.cas.flow.impl.CheckProxyAuthorizationAction" scope="prototype" />
<bean id="ValidateProxyCallback"
- class="net.shibboleth.idp.cas.flow.impl.ValidateProxyCallbackAction"
+ class="net.shibboleth.idp.cas.flow.impl.ValidateProxyCallbackAction" scope="prototype"
c:proxyAuthenticator="#{getObject('shibboleth.CASProxyAuthenticator') ?: getObject('shibboleth.DefaultCASProxyAuthenticator')}"
c:ticketService="#{getObject('shibboleth.CASTicketService') ?: getObject('shibboleth.DefaultCASTicketService')}" />
<bean id="PrepareTicketValidationResponse"
- class="net.shibboleth.idp.cas.flow.impl.PrepareTicketValidationResponseAction"
+ class="net.shibboleth.idp.cas.flow.impl.PrepareTicketValidationResponseAction" scope="prototype"
p:transcoderRegistry-ref="shibboleth.AttributeRegistryService" />
<bean id="UpdateIdPSessionWithSPSession"
- class="net.shibboleth.idp.cas.flow.impl.UpdateIdPSessionWithSPSessionAction"
+ class="net.shibboleth.idp.cas.flow.impl.UpdateIdPSessionWithSPSessionAction" scope="prototype"
c:lifetime="%{idp.session.defaultSPlifetime:PT2H}"
c:resolver-ref="shibboleth.SessionManager" />
@@ -55,4 +55,5 @@
<!-- Supplementary beans -->
<bean id="PrincipalLookupFunction" class="net.shibboleth.idp.cas.ticket.TicketPrincipalLookupFunction" />
+
</beans>
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/system/flows/cas/validate/validate-beans.xml b/idp-conf/src/main/resources/system/flows/cas/validate/validate-beans.xml
index 5faedfe..8829027 100644
--- a/idp-conf/src/main/resources/system/flows/cas/validate/validate-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/cas/validate/validate-beans.xml
@@ -2,21 +2,23 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-init-method="initialize">
<bean id="WriteValidateSuccess"
- class="net.shibboleth.idp.cas.flow.impl.WriteValidateResponseAction"
- c:successFlag="true" />
+ class="net.shibboleth.idp.cas.flow.impl.WriteValidateResponseAction" scope="prototype"
+ c:successFlag="true"
+ p:httpServletResponse-ref="shibboleth.HttpServletResponse" />
<bean id="WriteValidateFailure"
- class="net.shibboleth.idp.cas.flow.impl.WriteValidateResponseAction"
- c:successFlag="false" />
+ class="net.shibboleth.idp.cas.flow.impl.WriteValidateResponseAction" scope="prototype"
+ c:successFlag="false"
+ p:httpServletResponse-ref="shibboleth.HttpServletResponse" />
<bean id="RecordResponseComplete"
- class="net.shibboleth.idp.profile.impl.RecordResponseComplete"
- scope="prototype" />
+ class="net.shibboleth.idp.profile.impl.RecordResponseComplete" scope="prototype" />
</beans>
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list