[java-identity-provider] branch main updated: IDP-2069 - Null Handling Task

Rod Widdowson rdw at steadingsoftware.com
Mon Apr 10 15:20:53 UTC 2023


This is an automated email from the git hooks/post-receive script.

rdw pushed a commit to branch main
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=203caa4dce9353203ee9df71fc1917c8850506fe

The following commit(s) were added to refs/heads/main by this push:
     new 203caa4dc IDP-2069 - Null Handling Task
203caa4dc is described below

commit 203caa4dce9353203ee9df71fc1917c8850506fe
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Mon Apr 10 15:25:40 2023 +0100

    IDP-2069 - Null Handling Task
    
    https://shibboleth.atlassian.net/browse/IDP-2069
    
    Start adding and exploiting the @NonnullBeforeExec annotations
    
      idp-admin-impl
      idp-authn-api
      idp-authn-impl
      idp-cas-impl
---
 .../idp/admin/impl/DoStorageOperation.java         | 31 ++++++-----
 ...InitializeAdministrativeProfileContextTree.java | 26 ++++++---
 .../shibboleth/idp/admin/impl/OutputMetrics.java   |  5 +-
 .../idp/authn/AbstractAuthenticationAction.java    | 35 ++++++------
 .../AbstractSubjectCanonicalizationAction.java     | 31 ++++++-----
 .../idp/authn/impl/DoLockoutManagerOperation.java  | 25 ++++++---
 .../impl/DoRevocationCacheOperation.java           | 64 ++++++++++++++++------
 .../impl/BuildAuthenticationContextAction.java     |  9 ++-
 .../idp/cas/flow/impl/BuildProxyChainAction.java   | 11 ++--
 .../flow/impl/BuildRelyingPartyContextAction.java  |  3 +-
 .../flow/impl/BuildSAMLMetadataContextAction.java  | 30 ++++++----
 .../flow/impl/CheckProxyAuthorizationAction.java   | 10 ++--
 .../idp/cas/flow/impl/GrantProxyTicketAction.java  | 49 +++++++++--------
 .../cas/flow/impl/GrantServiceTicketAction.java    | 44 +++++++--------
 .../PrepareTicketValidationResponseAction.java     | 26 ++++-----
 .../impl/UpdateIdPSessionWithSPSessionAction.java  | 16 +++---
 .../cas/flow/impl/ValidateProxyCallbackAction.java | 41 +++++++-------
 .../idp/cas/flow/impl/ValidateRenewAction.java     | 13 ++---
 .../idp/cas/flow/impl/ValidateTicketAction.java    | 21 +++----
 .../cas/flow/impl/WriteValidateResponseAction.java |  9 ++-
 .../idp/saml/session/impl/AddLogoutRequest.java    |  6 +-
 21 files changed, 273 insertions(+), 232 deletions(-)

diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DoStorageOperation.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DoStorageOperation.java
index dcf8e3bf2..a14d39b75 100644
--- a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DoStorageOperation.java
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/DoStorageOperation.java
@@ -44,6 +44,7 @@ import com.google.common.base.Strings;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.idp.profile.context.SpringRequestContext;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
@@ -79,13 +80,13 @@ public class DoStorageOperation extends AbstractProfileAction {
     @NonnullAfterInit private ObjectMapper objectMapper;
     
     /** {@link StorageService} to operate on. */
-    @Nullable private StorageService storageService;
+    @NonnullBeforeExec private StorageService storageService;
     
     /** Storage context to operate on. */
-    @Nullable @NotEmpty private String context;
+    @NonnullBeforeExec @NotEmpty private String context;
 
     /** Storage key to operate on. */
-    @Nullable @NotEmpty private String key;
+    @NonnullBeforeExec @NotEmpty private String key;
 
     /**
      * Set the JSON {@link ObjectMapper} to use for serialization.
@@ -123,15 +124,19 @@ public class DoStorageOperation extends AbstractProfileAction {
     /** Null safe key getter.
      * @return Returns the key.
      */
-    @Nonnull private String getKeyInExecute() {
-        return Constraint.isNotNull(key, "null key not detected in preExecute");
+    @SuppressWarnings("null")
+    @Nonnull private String getKey() {
+        assert isPreExecuteCalled();
+        return key;
     }
 
     /** Null safe context getter.
      * @return Returns the context.
      */
-    @Nonnull private String getContextInExecute() {
-        return Constraint.isNotNull(context, "null context not detected in preExecute");
+    @SuppressWarnings("null")
+    @Nonnull private String getContext() {
+        assert isPreExecuteCalled();
+        return context;
     }
 
 // Checkstyle: CyclomaticComplexity OFF
@@ -249,7 +254,7 @@ public class DoStorageOperation extends AbstractProfileAction {
         try {
             @Nonnull final StorageService storageServ = Constraint.isNotNull(storageService, "Null storge service not detected in preExecute");
             @Nonnull final HttpServletResponse response = Constraint.isNotNull(getHttpServletResponse(), "No Servlet response present");
-            record = storageServ.read(getContextInExecute(), getKeyInExecute());
+            record = storageServ.read(getContext(), getKey());
             if (record != null) {
                 response.setStatus(HttpServletResponse.SC_OK);
                 final JsonFactory jsonFactory = new JsonFactory();
@@ -312,7 +317,7 @@ public class DoStorageOperation extends AbstractProfileAction {
             throw new IOException("Input missing 'val' field");
         }
         
-        if (storageServ.create(getContextInExecute(), getKeyInExecute(), value, exp)) {
+        if (storageServ.create(getContext(), getKey(), value, exp)) {
             response.setStatus(HttpServletResponse.SC_CREATED);
         } else {
             sendError(HttpServletResponse.SC_CONFLICT, "Duplicate Record",
@@ -360,7 +365,7 @@ public class DoStorageOperation extends AbstractProfileAction {
         
         if (version != null) {
             try {
-                version = storageServ.updateWithVersion(version, getContextInExecute(), getKeyInExecute(), value, exp);
+                version = storageServ.updateWithVersion(version, getContext(), getKey(), value, exp);
                 if (version != null) {
                     response.setStatus(HttpServletResponse.SC_OK);
                 } else {
@@ -370,9 +375,9 @@ public class DoStorageOperation extends AbstractProfileAction {
                 sendError(HttpServletResponse.SC_CONFLICT, "Version Mismatch", "Record version did not match.");
             }
         } else {
-            if (storageServ.update(getContextInExecute(), getKeyInExecute(), value, exp)) {
+            if (storageServ.update(getContext(), getKey(), value, exp)) {
                 response.setStatus(HttpServletResponse.SC_OK);
-            } else if (storageServ.create(getContextInExecute(), getKeyInExecute(), value, exp)) {
+            } else if (storageServ.create(getContext(), getKey(), value, exp)) {
                 response.setStatus(HttpServletResponse.SC_CREATED);
             } else {
                 sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error",
@@ -392,7 +397,7 @@ public class DoStorageOperation extends AbstractProfileAction {
             @Nonnull final StorageService storageServ = Constraint.isNotNull(storageService, "Null storge service not detected in preExecute");
             @Nonnull final HttpServletResponse response = Constraint.isNotNull(getHttpServletResponse(), "No Servlet response present");
 
-            if (storageServ.delete(getContextInExecute(), getKeyInExecute())) {
+            if (storageServ.delete(getContext(), getKey())) {
                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
             } else {
                 sendError(HttpServletResponse.SC_NOT_FOUND,
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/InitializeAdministrativeProfileContextTree.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/InitializeAdministrativeProfileContextTree.java
index e88af670f..dda868b45 100644
--- a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/InitializeAdministrativeProfileContextTree.java
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/InitializeAdministrativeProfileContextTree.java
@@ -31,6 +31,7 @@ import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.idp.profile.IdPEventIds;
 import net.shibboleth.idp.ui.context.RelyingPartyUIContext;
 import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.NonnullSupplier;
@@ -56,7 +57,7 @@ public class InitializeAdministrativeProfileContextTree extends AbstractProfileA
     @Nonnull private final Logger log = LoggerFactory.getLogger(InitializeAdministrativeProfileContextTree.class);
     
     /** Descriptor of the administrative flow being run. */
-    @Nullable private AdministrativeFlowDescriptor flowDescriptor;
+    @NonnullBeforeExec private AdministrativeFlowDescriptor flowDescriptor;
 
     /** The system wide languages to inspect if there is no match between metadata and browser. */
     @Nullable private List<String> fallbackLanguages;
@@ -87,7 +88,16 @@ public class InitializeAdministrativeProfileContextTree extends AbstractProfileA
             fallbackLanguages = null;
         }
     }
-    
+
+    /**
+     * @return Returns the flowDescriptor.
+     */
+    @SuppressWarnings("null")
+    @Nonnull private AdministrativeFlowDescriptor getFlowDescriptor() {
+        assert isPreExecuteCalled();
+        return flowDescriptor;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -123,18 +133,16 @@ public class InitializeAdministrativeProfileContextTree extends AbstractProfileA
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         
-        final AdministrativeFlowDescriptor descriptor = flowDescriptor;
-        assert descriptor != null;
-        profileRequestContext.setLoggingId(descriptor.getLoggingId());
-        profileRequestContext.setBrowserProfile(!descriptor.isNonBrowserSupported(profileRequestContext));
+        profileRequestContext.setLoggingId(getFlowDescriptor().getLoggingId());
+        profileRequestContext.setBrowserProfile(!getFlowDescriptor().isNonBrowserSupported(profileRequestContext));
         
         final RelyingPartyContext rpCtx = new RelyingPartyContext();
         profileRequestContext.addSubcontext(rpCtx, true);
-        rpCtx.setRelyingPartyId(descriptor.getId());
-        rpCtx.setProfileConfig(descriptor);
+        rpCtx.setRelyingPartyId(getFlowDescriptor().getId());
+        rpCtx.setProfileConfig(getFlowDescriptor());
         
         final RelyingPartyUIContext uiCtx = rpCtx.ensureSubcontext(RelyingPartyUIContext.class);
-        uiCtx.setRPUInfo(descriptor.getUIInfo());
+        uiCtx.setRPUInfo(getFlowDescriptor().getUIInfo());
         final NonnullSupplier<HttpServletRequest> supplier = getHttpServletRequestSupplier();
         assert supplier != null;
         uiCtx.setBrowserLanguageRanges(SpringSupport.getLanguageRange(supplier.get()));
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
index 6787e2ca1..e6e588a32 100644
--- a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/OutputMetrics.java
@@ -50,6 +50,7 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.idp.profile.context.SpringRequestContext;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.collection.CollectionSupport;
@@ -93,7 +94,7 @@ public class OutputMetrics extends AbstractProfileAction {
     @Nullable private String jsonpCallbackName;
 
     /** Formatter for date/time fields. */
-    @Nonnull private DateTimeFormatter dateTimeFormatter;
+    @NonnullAfterInit private DateTimeFormatter dateTimeFormatter;
 
     /** Convert date/time fields to default time zone. */
     private boolean useDefaultTimeZone;
@@ -102,7 +103,7 @@ public class OutputMetrics extends AbstractProfileAction {
     @Nonnull @NonnullElements private Map<String,MetricFilter> metricFilterMap;
     
     /** Metric ID to operate on. */
-    @Nullable private String metricId;
+    @NonnullBeforeExec private String metricId;
     
     /** Constructor. */
     public OutputMetrics() {
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractAuthenticationAction.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractAuthenticationAction.java
index 7a3348af0..28d9f0a7a 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractAuthenticationAction.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractAuthenticationAction.java
@@ -20,17 +20,15 @@ package net.shibboleth.idp.authn;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.context.ProfileRequestContext;
-import org.slf4j.Logger;
 
 import net.shibboleth.idp.authn.context.AuthenticationContext;
 import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A base class for authentication related actions.
@@ -46,9 +44,6 @@ import net.shibboleth.shared.primitive.LoggerFactory;
 public abstract class AbstractAuthenticationAction
         extends AbstractProfileAction {
 
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractCredentialValidator.class);
-    
     /**
      * Strategy used to extract, and create if necessary, the {@link AuthenticationContext} from the
      * {@link ProfileRequestContext}.
@@ -56,7 +51,7 @@ public abstract class AbstractAuthenticationAction
     @Nonnull private Function<ProfileRequestContext,AuthenticationContext> authnCtxLookupStrategy;
     
     /** AuthenticationContext to operate on. */
-    @Nullable private AuthenticationContext authnContext;
+    @NonnullBeforeExec private AuthenticationContext authnContext;
 
     /** Constructor. */
     public AbstractAuthenticationAction() {
@@ -74,20 +69,28 @@ public abstract class AbstractAuthenticationAction
         
         authnCtxLookupStrategy = Constraint.isNotNull(strategy, "Strategy cannot be null");
     }
-    
+
+    /** null safe getter.
+     * @return Returns the authnContext.
+     */
+    @SuppressWarnings("null")
+    @Nonnull private AuthenticationContext getAuthenticationContext() {
+        assert isPreExecuteCalled();
+        return authnContext;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected final boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
         if (super.doPreExecute(profileRequestContext)) {
-            authnContext = authnCtxLookupStrategy.apply(profileRequestContext);
-            if (authnContext == null) {
+            final AuthenticationContext ac = authnContext = authnCtxLookupStrategy.apply(profileRequestContext);
+            if (ac  == null) {
                 ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_AUTHN_CTX);
                 return false;
             }
     
-            assert authnContext != null;
-            return doPreExecute(profileRequestContext, authnContext);
+            return doPreExecute(profileRequestContext, ac);
         }
         return false;
     }
@@ -95,13 +98,7 @@ public abstract class AbstractAuthenticationAction
     /** {@inheritDoc} */
     @Override
     protected final void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        if (authnContext == null) {
-            log.error("{} AuthenticationContext not populated", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_AUTHN_CTX);
-            return;
-        }
-        assert authnContext != null;
-        doExecute(profileRequestContext, authnContext);
+        doExecute(profileRequestContext, getAuthenticationContext());
     }
 
     /**
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractSubjectCanonicalizationAction.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractSubjectCanonicalizationAction.java
index 10d71389b..d986547cb 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractSubjectCanonicalizationAction.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractSubjectCanonicalizationAction.java
@@ -34,6 +34,7 @@ import org.slf4j.Logger;
 
 import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
 import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.collection.CollectionSupport;
@@ -66,8 +67,8 @@ public abstract class AbstractSubjectCanonicalizationAction
     @Nonnull private Function<ProfileRequestContext,SubjectCanonicalizationContext> scCtxLookupStrategy;
     
     /** {@link SubjectCanonicalizationContext} to operate on. */
-    @Nullable private SubjectCanonicalizationContext scContext;
-    
+    @NonnullBeforeExec private SubjectCanonicalizationContext scContext;
+
     /** Match patterns and replacement strings to apply. */
     @Nonnull @NonnullElements private List<Pair<Pattern,String>> transforms;
 
@@ -90,6 +91,15 @@ public abstract class AbstractSubjectCanonicalizationAction
         trim = false;
     }
 
+    /** Null safe getter.
+     * @return Returns the scContext.
+     */
+    @SuppressWarnings("null")
+    @Nonnull private SubjectCanonicalizationContext getSubjectCanonicalizationContext() {
+        assert isPreExecuteCalled();
+        return scContext;
+    }
+
     /**
      * Set the context lookup strategy.
      * 
@@ -155,14 +165,14 @@ public abstract class AbstractSubjectCanonicalizationAction
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         
         if (super.doPreExecute(profileRequestContext)) {
-            scContext = scCtxLookupStrategy.apply(profileRequestContext);
-            if (scContext == null) {
+            final SubjectCanonicalizationContext sc = scContext = scCtxLookupStrategy.apply(profileRequestContext);
+            if (sc == null) {
                 ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_SUBJECT_C14N_CTX);
                 return false;
             }
             
-            assert scContext != null;
-            return doPreExecute(profileRequestContext, scContext);
+            assert sc != null;
+            return doPreExecute(profileRequestContext, sc);
         }
         
         return false;
@@ -192,13 +202,7 @@ public abstract class AbstractSubjectCanonicalizationAction
     /** {@inheritDoc} */
     @Override
     protected final void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        if (scContext == null) {
-            log.error("{} SubjectCanonicalizationContext not populated", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_SUBJECT_C14N_CTX);
-            return;
-        }
-        assert scContext != null;
-        doExecute(profileRequestContext, scContext);
+        doExecute(profileRequestContext, getSubjectCanonicalizationContext());
     }
 
     /**
@@ -209,7 +213,6 @@ public abstract class AbstractSubjectCanonicalizationAction
      */
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
             @Nonnull final SubjectCanonicalizationContext c14nContext) {
-        
     }
     
     /**
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/DoLockoutManagerOperation.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/DoLockoutManagerOperation.java
index 169a3bd95..02ec35054 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/DoLockoutManagerOperation.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/DoLockoutManagerOperation.java
@@ -44,6 +44,7 @@ import net.shibboleth.idp.authn.context.LockoutManagerContext;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.idp.profile.context.SpringRequestContext;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
@@ -87,10 +88,10 @@ public class DoLockoutManagerOperation extends AbstractProfileAction {
     @Nullable @NotEmpty private String managerId;
 
     /** Account key to operate on. */
-    @Nullable @NotEmpty private String key;
+    @NonnullBeforeExec @NotEmpty private String key;
     
     /** {@link AccountLockoutManager} to operate on. */
-    @Nullable private AccountLockoutManager lockoutManager;
+    @NonnullBeforeExec private AccountLockoutManager lockoutManager;
 
     /**
      * Set the JSON {@link ObjectMapper} to use for serialization.
@@ -142,7 +143,7 @@ public class DoLockoutManagerOperation extends AbstractProfileAction {
                 return false;
             }
             
-            lockoutManager = getLockoutManager(requestContext);
+            lockoutManager = setupLockoutManager(requestContext);
             if (lockoutManager == null) {
                 sendError(HttpServletResponse.SC_NOT_FOUND,
                         "Invalid Lockout Manager", "Invalid lockout manager identifier in path.");
@@ -174,14 +175,12 @@ public class DoLockoutManagerOperation extends AbstractProfileAction {
             final HttpServletRequest request = getHttpServletRequest();
             final HttpServletResponse response = getHttpServletResponse();
             assert response != null && request != null;
-            final AccountLockoutManager lckManager = this.lockoutManager;
-            assert lckManager != null;
             response.setContentType("application/json");
             response.setHeader("Cache-Control", "must-revalidate,no-cache,no-store");
             
             if ("GET".equals(request.getMethod())) {
                 try {
-                    final boolean lockout = lckManager.check(profileRequestContext);
+                    final boolean lockout = getLockoutManager().check(profileRequestContext);
                     response.setStatus(HttpServletResponse.SC_OK);
                     final JsonFactory jsonFactory = new JsonFactory();
                     try (final JsonGenerator g = jsonFactory.createGenerator(
@@ -201,7 +200,7 @@ public class DoLockoutManagerOperation extends AbstractProfileAction {
                 
             } else if ("POST".equals(request.getMethod())) {
                 try {
-                    if (lckManager.increment(profileRequestContext)) {
+                    if (getLockoutManager().increment(profileRequestContext)) {
                         response.setStatus(HttpServletResponse.SC_NO_CONTENT);
                     } else {
                         throw new IOException();
@@ -213,7 +212,7 @@ public class DoLockoutManagerOperation extends AbstractProfileAction {
                 
             } else if ("DELETE".equals(request.getMethod())) {
                 try {
-                    if (lckManager.clear(profileRequestContext)) {
+                    if (getLockoutManager().clear(profileRequestContext)) {
                         response.setStatus(HttpServletResponse.SC_NO_CONTENT);
                     } else {
                         throw new IOException();
@@ -242,7 +241,7 @@ public class DoLockoutManagerOperation extends AbstractProfileAction {
      * 
      * @return lockout manager or null
      */
-    @Nullable private AccountLockoutManager getLockoutManager(@Nonnull final RequestContext requestContext) {
+    @Nullable private AccountLockoutManager setupLockoutManager(@Nonnull final RequestContext requestContext) {
         
         final String mgrId = this.managerId = (String) requestContext.getFlowScope().get(MANAGER_ID);
         if (mgrId == null) {
@@ -264,6 +263,14 @@ public class DoLockoutManagerOperation extends AbstractProfileAction {
         return null;
     }
 
+    /** Null safe getter.
+     * @return Returns the lockoutManager.
+     */
+    @Nonnull private AccountLockoutManager getLockoutManager() {
+        assert isPreExecuteCalled();
+        return lockoutManager;
+    }
+
     /**
      * Output an error object.
      * 
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/revocation/impl/DoRevocationCacheOperation.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/revocation/impl/DoRevocationCacheOperation.java
index cbfaa8680..b570388b5 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/revocation/impl/DoRevocationCacheOperation.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/revocation/impl/DoRevocationCacheOperation.java
@@ -22,7 +22,6 @@ import java.time.Duration;
 import java.util.Collections;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventIds;
@@ -41,11 +40,13 @@ import com.google.common.base.Strings;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.idp.profile.context.SpringRequestContext;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.xml.DOMTypeSupport;
+
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
@@ -87,16 +88,15 @@ public class DoRevocationCacheOperation extends AbstractProfileAction {
     @NonnullAfterInit private ObjectMapper objectMapper;
 
     /** Revocation Cache ID. */
-    @Nullable @NotEmpty private String cacheId;
-    
+    @NonnullBeforeExec @NotEmpty private String cacheId;
+
     /** Revocation context to operate on. */
-    @Nullable @NotEmpty private String context;
-    
+    @NonnullBeforeExec @NotEmpty private String context;
     /** Revocation key to operate on. */
-    @Nullable @NotEmpty private String key;
+    @NonnullBeforeExec @NotEmpty private String key;
 
     /** {@link RevocationCache} to operate on. */
-    @Nullable private RevocationCache revocationCache;
+    @NonnullBeforeExec private RevocationCache revocationCache;
 
     /**
      * Set the JSON {@link ObjectMapper} to use for serialization.
@@ -109,6 +109,38 @@ public class DoRevocationCacheOperation extends AbstractProfileAction {
         objectMapper = Constraint.isNotNull(mapper, "ObjectMapper cannot be null");
     }
 
+    /** Null safe getter.
+     * @return Returns the revocationCache.
+     */
+    @Nonnull private RevocationCache getRevocationCache() {
+        assert isPreExecuteCalled();
+        return revocationCache;
+    }
+
+    /** Null safe getter.
+     * @return Returns the cacheId.
+     */
+    @Nonnull private String getCacheId() {
+        assert isPreExecuteCalled();
+        return cacheId;
+    }
+
+    /** Null safe getter.
+     * @return Returns the key.
+     */
+    @Nonnull private String getKey() {
+        assert isPreExecuteCalled();
+        return key;
+    }
+
+    /** Null safe getter.
+     * @return Returns the context.
+     */
+    @Nonnull private String getContext() {
+        assert isPreExecuteCalled();
+        return context;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected void doInitialize() throws ComponentInitializationException {
@@ -151,19 +183,18 @@ public class DoRevocationCacheOperation extends AbstractProfileAction {
             }
             
             
-            cacheId = getParameter(requestContext, CACHE_ID);
+            final String cId = cacheId = getParameter(requestContext, CACHE_ID);
             context = getParameter(requestContext, CONTEXT);
             key = getParameter(requestContext, KEY);
             
-            if (Strings.isNullOrEmpty(cacheId) || Strings.isNullOrEmpty(context) || Strings.isNullOrEmpty(key)) {
+            if (Strings.isNullOrEmpty(cId) || Strings.isNullOrEmpty(context) || Strings.isNullOrEmpty(key)) {
                 sendError(HttpServletResponse.SC_NOT_FOUND,
                         "Missing revocation cache ID, context, or key",
                         "No revocation cache ID, context, key specified.");
                 return false;
             }
 
-            assert cacheId != null;
-            revocationCache = getBean(requestContext, cacheId, RevocationCache.class);
+            revocationCache = getBean(requestContext, cId, RevocationCache.class);
             if (revocationCache == null) {
                 sendError(HttpServletResponse.SC_NOT_FOUND,
                         "Invalid Revocation Cache", "Invalid revocation cache identifier in path.");
@@ -232,7 +263,7 @@ public class DoRevocationCacheOperation extends AbstractProfileAction {
                     g.writeStartObject();
                     g.writeObjectFieldStart("data");
                     g.writeStringField("type", "revocation-records");
-                    g.writeStringField("id", cacheId + '/' + context + '/' + key);
+                    g.writeStringField("id", getCacheId()  + '/' + context + '/' + key);
                     g.writeObjectFieldStart("attributes");
                     g.writeStringField("revocation", revocation);
                 }
@@ -281,11 +312,9 @@ public class DoRevocationCacheOperation extends AbstractProfileAction {
         
         final boolean result;
         if (durationSeconds != null) {
-            assert revocationCache!=null && context!=null && key!=null;
-            result = revocationCache.revoke(context, key, value, durationSeconds);
+            result = getRevocationCache().revoke(getContext(), getKey(), value, durationSeconds);
         } else {
-            assert revocationCache!=null && context!=null && key!=null;
-            result = revocationCache.revoke(context, key, value);
+            result = getRevocationCache().revoke(getContext(), getKey(), value);
         }
         
         if (result) {
@@ -304,8 +333,7 @@ public class DoRevocationCacheOperation extends AbstractProfileAction {
     private void doDelete() throws IOException {
         final HttpServletResponse response = getHttpServletResponse();
         assert response != null;
-        assert revocationCache!=null && context!=null && key!=null;
-        if (revocationCache.unrevoke(context, key)) {
+        if (getRevocationCache().unrevoke(getContext(), getKey())) {
             response.setStatus(HttpServletResponse.SC_NO_CONTENT);
         } else {
             response.setStatus(HttpServletResponse.SC_NOT_FOUND);
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 65ca4e19e..ce031145c 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
@@ -25,6 +25,7 @@ import net.shibboleth.idp.cas.config.ConfigLookupFunction;
 import net.shibboleth.idp.cas.config.LoginConfiguration;
 import net.shibboleth.idp.cas.protocol.ServiceTicketRequest;
 import net.shibboleth.idp.cas.protocol.ServiceTicketResponse;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
@@ -42,7 +43,7 @@ public class BuildAuthenticationContextAction
     @Nonnull private final ConfigLookupFunction<LoginConfiguration> configLookupFunction;
 
     /** Stores off CAS request. */
-    @Nullable private ServiceTicketRequest request;
+    @NonnullBeforeExec private ServiceTicketRequest request;
     
     /** Constructor. */
     public BuildAuthenticationContextAction() {
@@ -69,10 +70,8 @@ public class BuildAuthenticationContextAction
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
         final AuthenticationContext ac = new AuthenticationContext();
-        final ServiceTicketRequest req = request;
-        assert req != null;
         
-        ac.setForceAuthn(req.isRenew());
+        ac.setForceAuthn(request.isRenew());
 
         final LoginConfiguration config = configLookupFunction.apply(profileRequestContext);
 
@@ -83,7 +82,7 @@ public class BuildAuthenticationContextAction
         }
         
         if (!ac.isForceAuthn()) {
-            ac.setIsPassive(req.isGateway());
+            ac.setIsPassive(request.isGateway());
         }
         
         if (config != null) {
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 6f468bb93..cc7f445e9 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
@@ -20,7 +20,6 @@ package net.shibboleth.idp.cas.flow.impl;
 import java.time.Instant;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
@@ -34,6 +33,7 @@ import net.shibboleth.idp.cas.ticket.ProxyGrantingTicket;
 import net.shibboleth.idp.cas.ticket.ProxyTicket;
 import net.shibboleth.idp.cas.ticket.Ticket;
 import net.shibboleth.idp.cas.ticket.TicketService;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 /**
@@ -57,10 +57,10 @@ public class BuildProxyChainAction
     @Nonnull private final TicketService casTicketService;
     
     /** Response. */
-    @Nullable private TicketValidationResponse response;
+    @NonnullBeforeExec private TicketValidationResponse response;
     
     /** Ticket. */
-    @Nullable private Ticket ticket;
+    @NonnullBeforeExec private Ticket ticket;
 
     /**
      * Constructor.
@@ -95,10 +95,8 @@ public class BuildProxyChainAction
             ActionSupport.buildEvent(profileRequestContext, ProtocolError.InvalidTicketType.event(this));
             return;
         }
-        final ProxyTicket pt = (ProxyTicket) ticket;
-        assert pt != null;
         ProxyGrantingTicket pgt;
-        String pgtId = pt.getPgtId();
+        String pgtId = ((ProxyTicket) ticket).getPgtId();
         do {
             pgt = casTicketService.fetchProxyGrantingTicket(pgtId);
             if (pgt == null || Instant.now().isAfter(pgt.getExpirationInstant())) {
@@ -106,7 +104,6 @@ public class BuildProxyChainAction
                 ActionSupport.buildEvent(profileRequestContext, ProtocolError.BrokenProxyChain.event(this));
                 return;
             }
-            assert response != null;
             response.addProxy(pgt.getProxyCallbackUrl());
             pgtId = pgt.getParentId();
         } while (pgtId != null);
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 18d7a9bb8..6e962b026 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
@@ -34,6 +34,7 @@ import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
 import net.shibboleth.idp.cas.service.Service;
 import net.shibboleth.idp.cas.service.ServiceRegistry;
 import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.collection.CollectionSupport;
@@ -63,7 +64,7 @@ public class BuildRelyingPartyContextAction<RequestType,ResponseType>
     @Nonnull @NonnullElements @NotEmpty private final List<ServiceRegistry> serviceRegistries;
     
     /** Request. */
-    @Nullable private Object request;
+    @NonnullBeforeExec private Object request;
 
     /**
      * Creates a new instance.
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 4f49c17e1..f89483bee 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,7 +18,6 @@
 package net.shibboleth.idp.cas.flow.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
@@ -31,6 +30,7 @@ import net.shibboleth.idp.cas.service.Service;
 import net.shibboleth.idp.cas.service.impl.ServiceEntityDescriptor;
 import net.shibboleth.idp.profile.IdPEventIds;
 import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 
 /**
  * Builds a {@link SAMLMetadataContext} child of {@link RelyingPartyContext} to facilitate relying party selection
@@ -52,10 +52,10 @@ public class BuildSAMLMetadataContextAction<RequestType,ResponseType>
     private boolean relyingPartyIdFromMetadata;
     
     /** CAS service. */
-    @Nullable private Service service;
+    @NonnullBeforeExec private Service service;
     
     /** RelyingPartyContext. */
-    @Nullable private RelyingPartyContext rpCtx;
+    @NonnullBeforeExec private RelyingPartyContext rpCtx;
     
     /**
      * Sets whether the {@link RelyingPartyContext#getRelyingPartyId()} method should return an entityID
@@ -70,6 +70,15 @@ public class BuildSAMLMetadataContextAction<RequestType,ResponseType>
         relyingPartyIdFromMetadata = flag;
     }
     
+    /** null safe getter
+     * @return Returns the service.
+     */
+    @SuppressWarnings("null")
+    @Nonnull public Service getService() {
+        assert isPreExecuteCalled();
+        return service;
+    }
+
     @Override
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         if (!super.doPreExecute(profileRequestContext)) {
@@ -96,20 +105,17 @@ public class BuildSAMLMetadataContextAction<RequestType,ResponseType>
     protected void doExecute(final @Nonnull ProfileRequestContext profileRequestContext) {
         
         final SAMLMetadataContext mdCtx = new SAMLMetadataContext();
-        final Service svc = service;
-        assert svc != null;
-        final EntityDescriptor entity = svc.getEntityDescriptor() != null
-                ? svc.getEntityDescriptor()
-                : new ServiceEntityDescriptor(svc);
+        EntityDescriptor entity = getService().getEntityDescriptor();
+        if (entity == null) {
+            entity = new ServiceEntityDescriptor(getService());
+        }
         mdCtx.setEntityDescriptor(entity);
-        mdCtx.setRoleDescriptor(svc.getRoleDescriptor());
+        mdCtx.setRoleDescriptor(getService().getRoleDescriptor());
         
         if (relyingPartyIdFromMetadata) {
-            assert rpCtx != null;
             rpCtx.setRelyingPartyId(entity.getEntityID());
         }
-        
-        assert rpCtx != null;
+
         rpCtx.setRelyingPartyIdContextTree(mdCtx);
     }
 
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 db6e82f29..7ba781a99 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,7 +18,6 @@
 package net.shibboleth.idp.cas.flow.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
@@ -28,6 +27,7 @@ import org.slf4j.Logger;
 import net.shibboleth.idp.cas.protocol.ProtocolError;
 import net.shibboleth.idp.cas.service.Service;
 import net.shibboleth.idp.cas.service.ServiceContext;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.primitive.LoggerFactory;   
 
 /**
@@ -50,7 +50,7 @@ public class CheckProxyAuthorizationAction<RequestType,ResponseType>
     @Nonnull private final Logger log = LoggerFactory.getLogger(CheckProxyAuthorizationAction.class);
 
     /** CAS service. */
-    @Nullable private Service service;
+    @NonnullBeforeExec private Service service;
     
     @Override
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -71,10 +71,8 @@ public class CheckProxyAuthorizationAction<RequestType,ResponseType>
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
-        final Service svc = service;
-        assert svc != null;
-        if (!svc.isAuthorizedToProxy()) {
-            log.info("{} Service '{}' is not authorized to proxy", getLogPrefix(), svc.getName());
+        if (!service.isAuthorizedToProxy()) {
+            log.info("{} Service '{}' is not authorized to proxy", getLogPrefix(), service.getName());
             ActionSupport.buildEvent(profileRequestContext, ProtocolError.ProxyNotAuthorized.event(this));
         }
     }
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 0bc35b5fe..c139be3a2 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,7 +21,6 @@ import java.time.Instant;
 import java.util.function.Predicate;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
@@ -45,6 +44,7 @@ import net.shibboleth.idp.session.IdPSession;
 import net.shibboleth.idp.session.SessionException;
 import net.shibboleth.idp.session.SessionResolver;
 import net.shibboleth.idp.session.criterion.SessionIdCriterion;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.logic.PredicateSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
@@ -78,16 +78,16 @@ public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicke
     @Nonnull private Predicate<ProfileRequestContext> validateIdPSessionPredicate;
 
     /** Profile config. */
-    @Nullable private ProxyConfiguration proxyConfig;
+    @NonnullBeforeExec private ProxyConfiguration proxyConfig;
     
     /** Security config. */
-    @Nullable private SecurityConfiguration securityConfig;
+    @NonnullBeforeExec private SecurityConfiguration securityConfig;
     
     /** CAS ticket. */
-    @Nullable private ProxyGrantingTicket proxyGrantingTicket;
+    @NonnullBeforeExec private ProxyGrantingTicket proxyGrantingTicket;
     
     /** CAS request. */
-    @Nullable private ProxyTicketRequest request;
+    @NonnullBeforeExec private ProxyTicketRequest request;
 
     /**
      * Constructor.
@@ -146,14 +146,21 @@ public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicke
         }
         
         return true;
-    }    
+    }
+
+    /** Null-safe getter
+     * @return Returns the proxyGrantingTicket.
+     */
+    @SuppressWarnings("null")
+    @Nonnull private ProxyGrantingTicket getProxyGrantingTicket() {
+        assert isPreExecuteCalled();
+        return proxyGrantingTicket;
+    }
     
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
-        ProxyGrantingTicket pgt = proxyGrantingTicket;
-        assert pgt != null;
-        if (pgt.getExpirationInstant().isBefore(Instant.now())) {
+        if (proxyGrantingTicket.getExpirationInstant().isBefore(Instant.now())) {
             ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketExpired.event(this));
             return;
         }
@@ -161,19 +168,19 @@ public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicke
         if (validateIdPSessionPredicate.test(profileRequestContext)) {
             IdPSession session = null;
             try {
-                log.debug("{} Attempting to retrieve session {}", getLogPrefix(), pgt.getSessionId());
+                log.debug("{} Attempting to retrieve session {}", getLogPrefix(), proxyGrantingTicket.getSessionId());
                 session = sessionResolver.resolveSingle(new CriteriaSet(new SessionIdCriterion(
-                        Constraint.isNotNull(pgt.getSessionId(), "ProxyGrantingTicket session id was null"))));
+                        Constraint.isNotNull(proxyGrantingTicket.getSessionId(), "ProxyGrantingTicket session id was null"))));
             } catch (final ResolverException e) {
                 log.warn("{} IdPSession resolution error: {}", getLogPrefix(), e);
             }
             boolean expired = true;
             if (session == null) {
-                log.info("{} IdPSession {} not found", getLogPrefix(), pgt.getSessionId());
+                log.info("{} IdPSession {} not found", getLogPrefix(), proxyGrantingTicket.getSessionId());
             } else {
                 try {
                     expired = !session.checkTimeout();
-                    log.debug("{} Session {} expired={}", getLogPrefix(), pgt.getSessionId(), expired);
+                    log.debug("{} Session {} expired={}", getLogPrefix(), proxyGrantingTicket.getSessionId(), expired);
                 } catch (final SessionException e) {
                     log.warn("{} Error performing session timeout check: {}. Assuming session has expired.",
                             getLogPrefix(), e);
@@ -185,19 +192,15 @@ public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicke
             }
         }
         final ProxyTicket pt;
-        final ProxyTicketRequest ptr = request;
-        final ProxyConfiguration pCfg = proxyConfig;
-        final SecurityConfiguration sCfg = securityConfig;
-        assert ptr != null && pCfg != null && sCfg != null;
         try {
-            log.debug("{} Granting proxy ticket for {}", getLogPrefix(), ptr.getTargetService());
-            final Instant then =Instant.now().plus(pCfg.getTicketValidityPeriod(profileRequestContext));
+            log.debug("{} Granting proxy ticket for {}", getLogPrefix(), request.getTargetService());
+            final Instant then = Instant.now().plus(proxyConfig.getTicketValidityPeriod(profileRequestContext));
             assert then != null;
             pt = casTicketService.createProxyTicket(
-                    sCfg.getIdGenerator().generateIdentifier(),
+                    securityConfig.getIdGenerator().generateIdentifier(),
                     then,
-                    pgt,
-                    ptr.getTargetService());
+                    getProxyGrantingTicket(),
+                    request.getTargetService());
         } catch (final RuntimeException e) {
             log.error("Failed granting proxy ticket due to error.", e);
             ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketCreationError.event(this));
@@ -211,7 +214,7 @@ public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicke
             return;
         }
         
-        log.info("{} Granted proxy ticket for {}", getLogPrefix(), ptr.getTargetService());
+        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 b2a6bef4d..f7dbac3eb 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
@@ -49,6 +49,7 @@ import net.shibboleth.idp.profile.IdPEventIds;
 import net.shibboleth.idp.session.IdPSession;
 import net.shibboleth.idp.session.context.SessionContext;
 import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 
@@ -85,16 +86,16 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
     @Nonnull private final TicketService casTicketService;
 
     /** Profile config. */
-    @Nullable private LoginConfiguration loginConfig;
+    @NonnullBeforeExec private LoginConfiguration loginConfig;
     
     /** Security config. */
-    @Nullable private SecurityConfiguration securityConfig;
+    @NonnullBeforeExec private SecurityConfiguration securityConfig;
     
     /** IdP's session. */
-    @Nullable private IdPSession session;
+    @NonnullBeforeExec private IdPSession session;
     
     /** Authentication result. */
-    @Nullable private AuthenticationResult authnResult;
+    @NonnullBeforeExec private AuthenticationResult authnResult;
 
     /** Whether consent needs to be stored in ticket. */
     private boolean storeConsent;
@@ -103,7 +104,7 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
     @Nullable private AttributeContext attributeCtx;
 
     /** CAS request. */
-    @Nullable private ServiceTicketRequest request;
+    @NonnullBeforeExec private ServiceTicketRequest request;
 
     /**
      * Constructor.
@@ -116,10 +117,13 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
         configLookupFunction = new ConfigLookupFunction<>(LoginConfiguration.class);
         sessionContextFunction = new ChildContextLookup<>(SessionContext.class);
         authnCtxLookupFunction = new ChildContextLookup<>(AuthenticationContext.class);
-        principalLookupFunction = new SubjectContextPrincipalLookupFunction().compose(
+        final Function<ProfileRequestContext, String> plf = new SubjectContextPrincipalLookupFunction().compose(
                 new ChildContextLookup<>(SubjectContext.class));
-        attributeContextLookupStrategy = new ChildContextLookup<>(AttributeContext.class).compose(
+        final Function<ProfileRequestContext,AttributeContext> aclf = new ChildContextLookup<>(AttributeContext.class).compose(
                 new ChildContextLookup<>(RelyingPartyContext.class));
+        assert plf != null && aclf != null;
+        principalLookupFunction = plf;
+        attributeContextLookupStrategy = aclf;
     }
     
     /**
@@ -204,41 +208,36 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
                 
         final ServiceTicket ticket;
-        final ServiceTicketRequest stReq = request;
-        final AuthenticationResult aRes = authnResult;
-        final LoginConfiguration lCfg = loginConfig;
-        assert stReq != null && aRes != null && lCfg != null;
 
         try {
-            log.debug("{} Granting service ticket for {}", getLogPrefix(), stReq.getService());
-            assert session != null;
+            log.debug("{} Granting service ticket for {}", getLogPrefix(), request.getService());
             final TicketState state = new TicketState(
                     Constraint.isNotNull(session.getId(), "Session ID was non null"),
                     getPrincipalName(profileRequestContext),
-                    aRes.getAuthenticationInstant(),
-                    aRes.getAuthenticationFlowId());
+                    authnResult.getAuthenticationInstant(),
+                    authnResult.getAuthenticationFlowId());
             
             if (storeConsent) {
                 assert attributeCtx != null;
                 state.setConsentedAttributeIds(attributeCtx.getIdPAttributes().keySet());
             }
             
-            final Instant then = Instant.now().plus(lCfg.getTicketValidityPeriod(profileRequestContext)); 
-            assert securityConfig != null && then != null;
+            final Instant then = Instant.now().plus(loginConfig.getTicketValidityPeriod(profileRequestContext)); 
+            assert then != null;
             ticket = casTicketService.createServiceTicket(
                     securityConfig.getIdGenerator().generateIdentifier(),
                     then,
-                    stReq.getService(),
+                    request.getService(),
                     state,
-                    stReq.isRenew());
+                    request.isRenew());
         } catch (final RuntimeException e) {
             log.error("{} Failed granting service ticket due to error.", getLogPrefix(), e);
             ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketCreationError.event(this));
             return;
         }
         
-        final ServiceTicketResponse response = new ServiceTicketResponse(stReq.getService(), ticket.getId());
-        if (stReq.isSAML()) {
+        final ServiceTicketResponse response = new ServiceTicketResponse(request.getService(), ticket.getId());
+        if (request.isSAML()) {
             response.setSaml(true);
         }
         
@@ -249,7 +248,7 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
             return;
         }
 
-        log.info("{} Granted service ticket for {}", getLogPrefix(), stReq.getService());
+        log.info("{} Granted service ticket for {}", getLogPrefix(), request.getService());
     }
 
     /**
@@ -288,7 +287,6 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
     @Nullable private AuthenticationResult getLatestAuthenticationResult() {
         AuthenticationResult latest = null;
 
-        assert session != null;
         for (final AuthenticationResult result : session.getAuthenticationResults()) {
             if (latest == null || result.getAuthenticationInstant().isAfter(latest.getAuthenticationInstant())) {
                 latest = result;
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 b145aedb1..332bf8e50 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
@@ -55,6 +55,7 @@ import net.shibboleth.idp.profile.IdPEventIds;
 import net.shibboleth.profile.context.RelyingPartyContext;
 import net.shibboleth.shared.annotation.constraint.Live;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
@@ -95,22 +96,23 @@ public class PrepareTicketValidationResponseAction extends
     @NonnullAfterInit private TranscodingRule defaultTranscodingRule;
     
     /** Stored off context from request. */
-    @Nullable private AttributeContext attributeContext;
+    @NonnullBeforeExec private AttributeContext attributeContext;
     
     /** Stored consented attributes from ticket. */
     @Nullable private Set<String> consentedAttributeIds;
     
     /** Profile configuration. */
-    @Nullable private ValidateConfiguration validateConfiguration;
+    @NonnullBeforeExec private ValidateConfiguration validateConfiguration;
     
     /** CAS response. */
-    @Nullable private TicketValidationResponse ticketValidationResponse;
+    @NonnullBeforeExec private TicketValidationResponse ticketValidationResponse;
 
     /** Constructor. */
     public PrepareTicketValidationResponseAction() {
-        attributeContextFunction =
-                new ChildContextLookup<>(AttributeContext.class, true).compose(
-                        new ChildContextLookup<>(RelyingPartyContext.class));
+        final Function<ProfileRequestContext,AttributeContext> acf = new ChildContextLookup<>(AttributeContext.class, true).compose(
+                new ChildContextLookup<>(RelyingPartyContext.class));
+        assert acf != null;
+        attributeContextFunction = acf;
         principalLookupFunction = new TicketPrincipalLookupFunction();
         configLookupFunction = new ConfigLookupFunction<>(ValidateConfiguration.class);
     }
@@ -179,14 +181,10 @@ public class PrepareTicketValidationResponseAction extends
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
         final String principal;
-        final AttributeContext aCtx = attributeContext;
-        TicketValidationResponse response = ticketValidationResponse;
-        assert aCtx != null && response != null;
-        assert validateConfiguration != null;
         final String userAttributeName = validateConfiguration.getUserAttribute(profileRequestContext);
         if (userAttributeName != null) {
             log.debug("{} Using {} for CAS username", getLogPrefix(), userAttributeName);
-            final IdPAttribute attribute = aCtx.getIdPAttributes().get(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) {
@@ -213,9 +211,9 @@ public class PrepareTicketValidationResponseAction extends
             throw new IllegalStateException("Principal cannot be null");
         }
 
-        response.setUserName(principal);
+        ticketValidationResponse.setUserName(principal);
         
-        final Collection<IdPAttribute> inputAttributes = aCtx.getIdPAttributes().values();
+        final Collection<IdPAttribute> inputAttributes = attributeContext.getIdPAttributes().values();
         final ArrayList<Attribute> encodedAttributes = new ArrayList<>(inputAttributes.size());
 
         try (final ServiceableComponent<AttributeTranscoderRegistry> component =
@@ -236,7 +234,7 @@ public class PrepareTicketValidationResponseAction extends
             return;
         }
         
-        encodedAttributes.forEach(a -> {assert a!=null; response.addAttribute(a);});
+        encodedAttributes.forEach(a -> {assert a!=null; ticketValidationResponse.addAttribute(a);});
     }
     // Checkstyle: CyclomaticComplexity ON
 
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 c665d8643..9aabeb818 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,7 +21,6 @@ import java.time.Duration;
 import java.time.Instant;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
@@ -36,6 +35,7 @@ import net.shibboleth.idp.session.SPSession;
 import net.shibboleth.idp.session.SessionException;
 import net.shibboleth.idp.session.SessionResolver;
 import net.shibboleth.idp.session.criterion.SessionIdCriterion;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
@@ -65,10 +65,10 @@ public class UpdateIdPSessionWithSPSessionAction<RequestType,ResponseType>
     @Nonnull private final Duration sessionLifetime;
 
     /** Ticket. */
-    @Nullable private Ticket ticket;
+    @NonnullBeforeExec private Ticket ticket;
     
     /** CAS service. */
-    @Nullable private Service service;
+    @NonnullBeforeExec private Service service;
 
     /**
      * Constructor.
@@ -107,12 +107,10 @@ public class UpdateIdPSessionWithSPSessionAction<RequestType,ResponseType>
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
         IdPSession session = null;
-        final Ticket tckt = ticket;
-        assert tckt != null;
         try {
-            log.debug("{} Attempting to retrieve session {}", getLogPrefix(), tckt.getSessionId());
+            log.debug("{} Attempting to retrieve session {}", getLogPrefix(), ticket.getSessionId());
             session = sessionResolver.resolveSingle(new CriteriaSet(new SessionIdCriterion(
-                    Constraint.isNotNull(tckt.getSessionId(), "Null Session Id"))));
+                    Constraint.isNotNull(ticket.getSessionId(), "Null Session Id"))));
         } catch (final ResolverException e) {
             log.warn("{} Possible sign of misconfiguration, IdPSession resolution error: {}", getLogPrefix(), e);
         }
@@ -122,10 +120,10 @@ public class UpdateIdPSessionWithSPSessionAction<RequestType,ResponseType>
             final Instant expiration = now.plus(sessionLifetime); 
             assert expiration != null;
             final SPSession sps = new CASSPSession(
-                    tckt.getService(),
+                    ticket.getService(),
                     now,
                     expiration,
-                    tckt.getId());
+                    ticket.getId());
             log.debug("{} Created SP session {}", getLogPrefix(), sps);
             try {
                 session.addSPSession(sps);
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 23ab1466b..7e7b05efa 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,10 +22,8 @@ import java.net.URISyntaxException;
 import java.time.Instant;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.apache.hc.core5.net.URIBuilder;
-
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
 import org.opensaml.profile.action.EventIds;
@@ -47,6 +45,7 @@ import net.shibboleth.idp.cas.ticket.ServiceTicket;
 import net.shibboleth.idp.cas.ticket.Ticket;
 import net.shibboleth.idp.cas.ticket.TicketService;
 import net.shibboleth.idp.profile.IdPEventIds;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
@@ -80,19 +79,19 @@ public class ValidateProxyCallbackAction
     @Nonnull private final TicketService casTicketService;
 
     /** Profile config. */
-    @Nullable private ValidateConfiguration validateConfig;
+    @NonnullBeforeExec private ValidateConfiguration validateConfig;
     
     /** Security config. */
-    @Nullable private SecurityConfiguration securityConfig;
+    @NonnullBeforeExec private SecurityConfiguration securityConfig;
     
     /** CAS ticket. */
-    @Nullable private Ticket ticket;
+    @NonnullBeforeExec private Ticket ticket;
 
     /** CAS request. */
-    @Nullable private TicketValidationRequest request;
+    @NonnullBeforeExec private TicketValidationRequest request;
 
     /** CAS response. */
-    @Nullable private TicketValidationResponse response;
+    @NonnullBeforeExec private TicketValidationResponse response;
     
     /**
      * Constructor.
@@ -108,6 +107,15 @@ public class ValidateProxyCallbackAction
         configLookupFunction = new ConfigLookupFunction<>(ValidateConfiguration.class);
     }
     
+    /** Null Safe getter.
+     * @return Returns the ticket.
+     */
+    @SuppressWarnings("null")
+    @Nonnull private Ticket getTicket() {
+        assert isPreExecuteCalled();
+        return ticket;
+    }
+
     @Override
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         if (!super.doPreExecute(profileRequestContext)) {
@@ -120,7 +128,6 @@ public class ValidateProxyCallbackAction
             return false;
         }
         
-        assert validateConfig != null;
         securityConfig = validateConfig.getSecurityConfiguration(profileRequestContext);
         if (securityConfig == null) {
             ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_SEC_CFG);
@@ -141,27 +148,21 @@ public class ValidateProxyCallbackAction
 
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        final ValidateConfiguration vCfg = validateConfig;
-        final SecurityConfiguration sCfg = securityConfig;
-        final Ticket tkt = ticket;
-        final TicketValidationRequest request = this.request;
-        final TicketValidationResponse response = this.response;
-        assert vCfg != null && sCfg != null && tkt != null && request != null && response != null;
         
-        @Nonnull final IdentifierGenerationStrategy pgtGenerator = sCfg.getIdGenerator();
-        @Nonnull final IdentifierGenerationStrategy pgtIOUGenerator = vCfg.getPGTIOUGenerator(profileRequestContext);
-        final Instant expiration = Instant.now().plus(vCfg.getTicketValidityPeriod(profileRequestContext));
+        @Nonnull final IdentifierGenerationStrategy pgtGenerator = securityConfig.getIdGenerator();
+        @Nonnull final IdentifierGenerationStrategy pgtIOUGenerator = validateConfig.getPGTIOUGenerator(profileRequestContext);
+        final Instant expiration = Instant.now().plus(validateConfig.getTicketValidityPeriod(profileRequestContext));
         assert expiration!=null;
         @Nonnull final String pgtId = pgtGenerator.generateIdentifier();
         final String pgtUrl = request.getPgtUrl();
         assert pgtUrl != null;
         final ProxyGrantingTicket pgt;
-        if (ticket instanceof ServiceTicket) {
+        if (getTicket() instanceof ServiceTicket) {
             pgt = casTicketService.createProxyGrantingTicket(
-                pgtId, expiration, (ServiceTicket) tkt, pgtUrl);
+                pgtId, expiration, (ServiceTicket) getTicket(), pgtUrl);
         } else {
             pgt = casTicketService.createProxyGrantingTicket(
-                pgtId, expiration, (ProxyTicket) tkt, pgtUrl);
+                pgtId, expiration, (ProxyTicket) getTicket(), pgtUrl);
         }
         // The ID of the proxy-granting ticket MAY be different from the generated value above.
         // ALWAYS use the value from the ticket object.
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 1486a37b8..be1455508 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,7 +18,6 @@
 package net.shibboleth.idp.cas.flow.impl;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
@@ -30,6 +29,7 @@ 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 net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.primitive.LoggerFactory;
 /**
  * Ensures that a service ticket validation request that specifies renew=true matches the renew flag on the ticket
@@ -48,10 +48,10 @@ public class ValidateRenewAction extends AbstractCASProtocolAction<TicketValidat
     @Nonnull private final Logger log = LoggerFactory.getLogger(ValidateRenewAction.class);
 
     /** CAS ticket. */
-    @Nullable private Ticket ticket;
+    @NonnullBeforeExec private Ticket ticket;
 
     /** CAS request. */
-    @Nullable private TicketValidationRequest request;
+    @NonnullBeforeExec private TicketValidationRequest request;
 
     @Override
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -73,11 +73,8 @@ public class ValidateRenewAction extends AbstractCASProtocolAction<TicketValidat
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
-        final Ticket localTicket = ticket;
-        final TicketValidationRequest localRequest = request; 
-        assert localTicket != null && localRequest != null;
         if (ticket instanceof ServiceTicket) {
-            if (localRequest.isRenew() != ((ServiceTicket) localTicket).isRenew()) {
+            if (request.isRenew() != ((ServiceTicket) ticket).isRenew()) {
                 log.debug("{} Renew=true requested at validation time but ticket not issued with renew=true",
                         getLogPrefix());
                 ActionSupport.buildEvent(profileRequestContext, ProtocolError.TicketNotFromRenew.event(this));
@@ -85,7 +82,7 @@ public class ValidateRenewAction extends AbstractCASProtocolAction<TicketValidat
             }
         } else {
             // Proxy ticket validation
-            if (localRequest.isRenew()) {
+            if (request.isRenew()) {
                 ActionSupport.buildEvent(profileRequestContext, ProtocolError.RenewIncompatibleWithProxy.event(this));
                 return;
             }
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 eda27667d..bb8c015b7 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,7 +20,6 @@ package net.shibboleth.idp.cas.flow.impl;
 import java.time.Instant;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventException;
@@ -38,6 +37,7 @@ import net.shibboleth.idp.cas.ticket.ProxyTicket;
 import net.shibboleth.idp.cas.ticket.Ticket;
 import net.shibboleth.idp.cas.ticket.TicketService;
 import net.shibboleth.idp.profile.IdPEventIds;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 
@@ -67,10 +67,10 @@ public class ValidateTicketAction extends AbstractCASProtocolAction<TicketValida
     @Nonnull private final TicketService casTicketService;
 
     /** Profile config. */
-    @Nullable private ValidateConfiguration validateConfig;
+    @NonnullBeforeExec private ValidateConfiguration validateConfig;
 
     /** CAS request. */
-    @Nullable private TicketValidationRequest request;
+    @NonnullBeforeExec private TicketValidationRequest request;
     
     /**
      * Constructor.
@@ -107,15 +107,12 @@ public class ValidateTicketAction extends AbstractCASProtocolAction<TicketValida
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
-        final TicketValidationRequest localRequest = request;
-        final ValidateConfiguration localValidateConfig = validateConfig;
-        assert localValidateConfig != null && localRequest != null;
         final Ticket ticket;
         try {
-            final String ticketId = localRequest.getTicket();
+            final String ticketId = request.getTicket();
             log.debug("Attempting to validate {}", ticketId);
             if (ticketId.startsWith(LoginConfiguration.DEFAULT_TICKET_PREFIX)) {
-                ticket = casTicketService.removeServiceTicket(localRequest.getTicket());
+                ticket = casTicketService.removeServiceTicket(request.getTicket());
             } else if (ticketId.startsWith(ProxyConfiguration.DEFAULT_TICKET_PREFIX)) {
                 ticket = casTicketService.removeProxyTicket(ticketId);
             } else {
@@ -137,10 +134,10 @@ public class ValidateTicketAction extends AbstractCASProtocolAction<TicketValida
             return;
         }
 
-        if (localValidateConfig.getServiceComparator(profileRequestContext).compare(
-                ticket.getService(), localRequest.getService()) != 0) {
+        if (validateConfig.getServiceComparator(profileRequestContext).compare(
+                ticket.getService(), request.getService()) != 0) {
             log.debug("{} Service issued for {} does not match {}", getLogPrefix(), ticket.getService(),
-                    localRequest.getService());
+                    request.getService());
             ActionSupport.buildEvent(profileRequestContext, ProtocolError.ServiceMismatch.event(this));
             return;
         }
@@ -153,7 +150,7 @@ public class ValidateTicketAction extends AbstractCASProtocolAction<TicketValida
             return;
         }
 
-        log.info("{} Successfully validated {} for {}", getLogPrefix(), localRequest.getTicket(), localRequest.getService());
+        log.info("{} Successfully validated {} for {}", getLogPrefix(), request.getTicket(), request.getService());
         
         if (ticket instanceof ProxyTicket) {
             ActionSupport.buildEvent(profileRequestContext, Events.ProxyTicketValidated.event(this));
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 68db3578c..250dece6f 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,10 +20,10 @@ package net.shibboleth.idp.cas.flow.impl;
 import java.io.IOException;
 import java.io.PrintWriter;
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import net.shibboleth.idp.cas.protocol.TicketValidationRequest;
 import net.shibboleth.idp.cas.protocol.TicketValidationResponse;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 
 import org.opensaml.profile.action.ActionSupport;
@@ -48,7 +48,7 @@ public class WriteValidateResponseAction extends
     private final boolean success;
 
     /** CAS response. */
-    @Nullable private TicketValidationResponse response;
+    @NonnullBeforeExec private TicketValidationResponse response;
     
     /**
      * Constructor.
@@ -78,15 +78,14 @@ public class WriteValidateResponseAction extends
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
-        final TicketValidationResponse localResponse = response;
         final HttpServletResponse servletResponse = getHttpServletResponse();
-        assert localResponse!=null && servletResponse!=null;
+        assert servletResponse!=null;
         try {
             servletResponse.setContentType(CONTENT_TYPE);
             final PrintWriter output = servletResponse.getWriter();
             if (success) {
                 output.print("yes\n");
-                output.print(localResponse.getUserName() + '\n');
+                output.print(response.getUserName() + '\n');
             } else {
                 output.print("no\n\n");
             }
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/session/impl/AddLogoutRequest.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/session/impl/AddLogoutRequest.java
index 46219f2b8..f240dd2f9 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/session/impl/AddLogoutRequest.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/session/impl/AddLogoutRequest.java
@@ -45,6 +45,7 @@ import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.idp.saml.session.SAML2SPSession;
 import net.shibboleth.idp.session.context.LogoutPropagationContext;
 import net.shibboleth.profile.config.navigate.IdentifierGenerationStrategyLookupFunction;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
 
@@ -83,10 +84,10 @@ public class AddLogoutRequest extends AbstractProfileAction {
     @Nonnull private Function<ProfileRequestContext,LogoutPropagationContext> logoutPropContextLookupStrategy;
     
     /** The generator to use. */
-    @Nullable private IdentifierGenerationStrategy idGenerator;
+    @NonnullBeforeExec private IdentifierGenerationStrategy idGenerator;
 
     /** The {@link SAML2SPSession} to base the inbound context on. */
-    @Nullable private SAML2SPSession saml2Session;
+    @NonnullBeforeExec private SAML2SPSession saml2Session;
 
     /** EntityID to populate into Issuer element. */
     @Nullable private String issuerId;
@@ -215,7 +216,6 @@ public class AddLogoutRequest extends AbstractProfileAction {
 
         final LogoutRequest object = requestBuilder.buildObject();
         
-        assert idGenerator!=null;
         object.setID(idGenerator.generateIdentifier());
         object.setIssueInstant(Instant.now());
         object.setVersion(SAMLVersion.VERSION_20);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list