This is the TemporaryTicketNonInteractiveAction just in case that helps: package edu.gatech.gtri.cas.web.flow;
import edu.gatech.gtri.cas.authentication.principal.AfwpTempTicketCredential; import org.apereo.cas.authentication.Credential; import org.apereo.cas.authentication.adaptive.AdaptiveAuthenticationPolicy; import org.apereo.cas.web.flow.actions.AbstractNonInteractiveCredentialsAction; import org.apereo.cas.web.flow.authentication.DefaultCasWebflowExceptionCatalog; import org.apereo.cas.web.flow.authentication.CasWebflowExceptionHandler; import org.apereo.cas.web.flow.resolver.CasDelegatingWebflowEventResolver; import org.apereo.cas.web.flow.resolver.CasWebflowEventResolver; import org.apereo.cas.web.support.WebUtils; import lombok.extern.slf4j.Slf4j; import lombok.val; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.webflow.execution.RequestContext; import org.apache.commons.lang3.StringUtils; import org.springframework.webflow.action.AbstractAction; import org.springframework.webflow.core.collection.LocalAttributeMap; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.Action; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.apereo.cas.web.flow.actions.AuthenticationExceptionHandlerAction; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.configuration.model.core.web.MessageBundleProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import edu.gatech.gtri.cas.authentication.casuseradmin.InvalidTempTicketException; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; /** * Fully overlaid here from the core implementation package, so CAS config uses this class instead of its own * version, as there is no conditional bean definition available for this class as of version 6.0.3. * <p> * This implementation uses custom <code>AfwpX509CertificateCredential</code> */ @Slf4j public class TemporaryTicketNonInteractiveAction extends AbstractNonInteractiveCredentialsAction { @Autowired private ConfigurableApplicationContext applicationContext; /** * Attribute to indicate the x509 certificate. */ private static final long serialVersionUID = 4789797148634156909L; public TemporaryTicketNonInteractiveAction(final CasDelegatingWebflowEventResolver initialAuthenticationAttemptWebflowEventResolver, final CasWebflowEventResolver serviceTicketRequestWebflowEventResolver, final AdaptiveAuthenticationPolicy adaptiveAuthenticationPolicy) { super(initialAuthenticationAttemptWebflowEventResolver, serviceTicketRequestWebflowEventResolver, adaptiveAuthenticationPolicy); } @Override protected Credential constructCredentialsFromRequest(final RequestContext context) { val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context); final String loginTicketHash = context.getRequestParameters().get( "onetimeTicket"); if (loginTicketHash != null && !loginTicketHash.isEmpty()) { return new AfwpTempTicketCredential(loginTicketHash); } return null; } /* @ConditionalOnMissingBean(name = "authenticationExceptionHandler2") @Bean public Action authenticationExceptionHandler() { Look at org/apereo/cas/web/flow/config/CasCoreWebflowConfiguration.java for reference. return new AuthenticationExceptionHandlerAction(handledAuthenticationExceptions(), MessageBundleProperties.DEFAULT_BUNDLE_PREFIX_AUTHN_FAILURE); }*/ @ConditionalOnMissingBean(name = "authenticationExceptionHandler2") @Bean public Action authenticationExceptionHandler() { val beans = applicationContext.getBeansOfType(CasWebflowExceptionHandler. class, false, true); val handlers = new ArrayList<>(beans.values()); AnnotationAwareOrderComparator.sort(handlers); return new AuthenticationExceptionHandlerAction(handlers); } @RefreshScope @Bean public DefaultCasWebflowExceptionCatalog handledAuthenticationExceptions() { System.out.println("--------- handleAuthenticationExceptions"); /* * Order is important here; We want the account policy exceptions to be handled * first before moving onto more generic errors. In the event that multiple handlers * are defined, where one fails due to account policy restriction and one fails * due to a bad password, we want the error associated with the account policy * to be processed first, rather than presenting a more generic error associated */ val errors = new DefaultCasWebflowExceptionCatalog();; errors.registerException(InvalidTempTicketException.class); // errors.add(javax.security.auth.login.AccountLockedException.class); // errors.add(javax.security.auth.login.CredentialExpiredException.class); // errors.add(javax.security.auth.login.AccountExpiredException.class); // errors.add(AccountDisabledException.class); // errors.add(InvalidLoginLocationException.class); // errors.add(AccountPasswordMustChangeException.class); // errors.add(InvalidLoginTimeException.class); // errors.add(javax.security.auth.login.AccountNotFoundException.class); // errors.add(javax.security.auth.login.FailedLoginException.class); // errors.add(UnauthorizedServiceForPrincipalException.class); // errors.add(PrincipalException.class); // errors.add(UnsatisfiedAuthenticationPolicyException.class); // errors.add(UnauthorizedAuthenticationException.class); // errors.addAll(casProperties.getAuthn().getExceptions().getExceptions()); return errors; } } On Friday, September 20, 2024 at 2:18:17 PM UTC-4 Neil Bhadsavle wrote: > While upgrading to CAS 7, I am running into issues with the Action we are > adding to the webflow saying it can no longer find the method: > > Here are the errors I am getting: > > casuseradmin-1 | 2024-09-20 15:03:15,051 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing > org.apereo.cas.web.flow.login.InitialAuthenticationRequestValidationAction@7ac00160; > > result = success> > casuseradmin-1 | 2024-09-20 15:03:15,051 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing [EvaluateAction@45fe3bfc expression = > initialAuthenticationRequestValidationAction, resultExpression = [null]]; > result = success> > casuseradmin-1 | 2024-09-20 15:03:15,052 DEBUG > [org.springframework.webflow.engine.Transition] - <Executing > [Transition@6080e1b6 on = success, to = ticketGrantingTicketCheck]> > casuseradmin-1 | 2024-09-20 15:03:15,052 DEBUG > [org.springframework.webflow.engine.Transition] - <Exiting state > 'initialAuthenticationRequestValidationCheck'> > casuseradmin-1 | 2024-09-20 15:03:15,052 DEBUG > [org.springframework.webflow.engine.ActionState] - <Entering state > 'ticketGrantingTicketCheck' of flow 'login'> > casuseradmin-1 | 2024-09-20 15:03:15,052 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Executing > [EvaluateAction@3a2eaea6 expression = ticketGrantingTicketCheckAction, > resultExpression = [null]]> > casuseradmin-1 | 2024-09-20 15:03:15,058 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Executing > org.apereo.cas.web.flow.login.TicketGrantingTicketCheckAction@68d8359a> > casuseradmin-1 | 2024-09-20 15:03:15,058 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing > org.apereo.cas.web.flow.login.TicketGrantingTicketCheckAction@68d8359a; > result = notExists> > casuseradmin-1 | 2024-09-20 15:03:15,058 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing [EvaluateAction@3a2eaea6 expression = > ticketGrantingTicketCheckAction, resultExpression = [null]]; result = > notExists> > casuseradmin-1 | 2024-09-20 15:03:15,059 DEBUG > [org.springframework.webflow.engine.Transition] - <Executing > [Transition@2a181fdd on = notExists, to = gatewayRequestCheck]> > casuseradmin-1 | 2024-09-20 15:03:15,059 DEBUG > [org.springframework.webflow.engine.Transition] - <Exiting state > 'ticketGrantingTicketCheck'> > casuseradmin-1 | 2024-09-20 15:03:15,059 DEBUG > [org.springframework.webflow.engine.DecisionState] - <Entering state > 'gatewayRequestCheck' of flow 'login'> > casuseradmin-1 | 2024-09-20 15:03:15,061 DEBUG > [org.springframework.webflow.engine.Transition] - <Executing > [Transition@e1476bb on = *, to = serviceAuthorizationCheck]> > casuseradmin-1 | 2024-09-20 15:03:15,062 DEBUG > [org.springframework.webflow.engine.Transition] - <Exiting state > 'gatewayRequestCheck'> > casuseradmin-1 | 2024-09-20 15:03:15,062 DEBUG > [org.springframework.webflow.engine.ActionState] - <Entering state > 'serviceAuthorizationCheck' of flow 'login'> > casuseradmin-1 | 2024-09-20 15:03:15,062 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Executing > [EvaluateAction@716ea9c3 expression = serviceAuthorizationCheck, > resultExpression = [null]]> > casuseradmin-1 | 2024-09-20 15:03:15,072 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Executing > org.apereo.cas.web.flow.ServiceAuthorizationCheckAction@3934d4c0> > casuseradmin-1 | 2024-09-20 15:03:15,073 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing org.apereo.cas.web.flow.ServiceAuthorizationCheckAction@3934d4c0; > result = success> > casuseradmin-1 | 2024-09-20 15:03:15,073 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing [EvaluateAction@716ea9c3 expression = serviceAuthorizationCheck, > resultExpression = [null]]; result = success> > casuseradmin-1 | 2024-09-20 15:03:15,073 DEBUG > [org.springframework.webflow.engine.Transition] - <Executing > [Transition@470e78d4 on = *, to = initializeLoginForm]> > casuseradmin-1 | 2024-09-20 15:03:15,073 DEBUG > [org.springframework.webflow.engine.Transition] - <Exiting state > 'serviceAuthorizationCheck'> > casuseradmin-1 | 2024-09-20 15:03:15,073 DEBUG > [org.springframework.webflow.engine.ActionState] - <Entering state > 'initializeLoginForm' of flow 'login'> > casuseradmin-1 | 2024-09-20 15:03:15,073 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Executing > [EvaluateAction@514d40e1 expression = initializeLoginAction, > resultExpression = [null]]> > casuseradmin-1 | 2024-09-20 15:03:15,078 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Executing > org.apereo.cas.web.flow.login.InitializeLoginAction@7f63fa0a> > casuseradmin-1 | 2024-09-20 15:03:15,079 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing org.apereo.cas.web.flow.login.InitializeLoginAction@7f63fa0a; > result = success> > casuseradmin-1 | 2024-09-20 15:03:15,079 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing [EvaluateAction@514d40e1 expression = initializeLoginAction, > resultExpression = [null]]; result = success> > casuseradmin-1 | 2024-09-20 15:03:15,079 DEBUG > [org.springframework.webflow.engine.Transition] - <Executing > [Transition@2a2c0e3f on = success, to = afterInitializeLoginForm]> > casuseradmin-1 | 2024-09-20 15:03:15,079 DEBUG > [org.springframework.webflow.engine.Transition] - <Exiting state > 'initializeLoginForm'> > casuseradmin-1 | 2024-09-20 15:03:15,079 DEBUG > [org.springframework.webflow.engine.ActionState] - <Entering state > 'afterInitializeLoginForm' of flow 'login'> > casuseradmin-1 | 2024-09-20 15:03:15,079 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Executing > [SetAction@27e2ca6f name = requestScope.initialized, value = true]> > casuseradmin-1 | 2024-09-20 15:03:15,080 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Finished > executing [SetAction@27e2ca6f name = requestScope.initialized, value = > true]; result = success> > casuseradmin-1 | 2024-09-20 15:03:15,080 DEBUG > [org.springframework.webflow.engine.Transition] - <Executing > [Transition@3fdf7956 on = success, to = startTempAuthenticate]> > casuseradmin-1 | 2024-09-20 15:03:15,080 DEBUG > [org.springframework.webflow.engine.Transition] - <Exiting state > 'afterInitializeLoginForm'> > casuseradmin-1 | 2024-09-20 15:03:15,080 DEBUG > [org.springframework.webflow.engine.ActionState] - <Entering state > 'startTempAuthenticate' of flow 'login'> > casuseradmin-1 | 2024-09-20 15:03:15,081 DEBUG > [org.springframework.webflow.execution.ActionExecutor] - <Executing > [EvaluateAction@78ddce4 expression = tempTicketCheck, resultExpression = > [null]]> > casuseradmin-1 | 2024-09-20 15:03:15,086 DEBUG > [org.springframework.webflow.engine.impl.FlowExecutionImpl] - <Attempting > to handle [org.springframework.webflow.execution.ActionExecutionException: > Exception thrown executing [EvaluateAction@78ddce4 expression = > tempTicketCheck, resultExpression = [null]] in state > 'startTempAuthenticate' of flow 'login' -- action execution attributes were > 'map[[empty]]'] with root cause > [org.springframework.expression.spel.SpelEvaluationException: EL1008E: > Property or field 'tempTicketCheck' cannot be found on object of type > 'org.springframework.webflow.engine.impl.RequestControlContextImpl' - maybe > not public or not valid?]> > casuseradmin-1 | 2024-09-20 15:03:15,087 DEBUG > [org.springframework.webflow.engine.impl.FlowExecutionImpl] - <Rethrowing > unhandled flow execution exception> > casuseradmin-1 | 2024-09-20 15:03:15,088 DEBUG > [org.apereo.cas.web.FlowExecutionExceptionResolver] - <Ignoring the > received exception > [org.springframework.webflow.execution.ActionExecutionException: Exception > thrown executing [EvaluateAction@78ddce4 expression = tempTicketCheck, > resultExpression = [null]] in state 'startTempAuthenticate' of flow 'login' > -- action execution attributes were 'map[[empty]]'] due to a type mismatch > with handler [[FlowHandlerMapping.DefaultFlowHandler@3d5f2f9f]]> > > 2024-09-20 15:03:15,092 ERROR > [org.apereo.cas.web.support.filters.AbstractSecurityFilter] - <Request > processing failed: > org.springframework.webflow.execution.ActionExecutionException: Exception > thrown executing [EvaluateAction@78ddce4 expression = tempTicketCheck, > resultExpression = [null]] in state 'startTempAuthenticate' of flow 'login' > -- action execution attributes were 'map[[empty]]'> > > 2024-09-20 15:03:15,094 ERROR > [org.springframework.boot.web.servlet.support.ErrorPageFilter] - > <Forwarding to error page from request [/login] due to exception > [jakarta.servlet.ServletException: Request processing failed: > org.springframework.webflow.execution.ActionExecutionException: Exception > thrown executing [EvaluateAction@78ddce4 expression = tempTicketCheck, > resultExpression = [null]] in state 'startTempAuthenticate' of flow 'login' > -- action execution attributes were 'map[[empty]]']> > > Here is the method that sets up startTempAuthenticate: > > @Bean(name = "tempTicketCheck") > public Action tempTicketCheck() { > return new > TemporaryTicketNonInteractiveAction(initialAuthenticationAttemptWebflowEventResolver.getIfAvailable(), > serviceTicketRequestWebflowEventResolver.getIfAvailable(), > adaptiveAuthenticationPolicy.getIfAvailable()); > } > > > Here is the doInitialize setting up the webflow: > > @Override > protected void doInitialize() { > val flow = getLoginFlow(); > if (flow != null) { > val actionState = createActionState(flow, > CasWebflowConstants.STATE_ID_X509_START, > CasWebflowConstants.ACTION_ID_X509_CHECK); > val transitionSet = actionState.getTransitionSet(); > > //Adding x509 webflow transition > > transitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_SUCCESS, > CasWebflowConstants.STATE_ID_CREATE_TICKET_GRANTING_TICKET)); > transitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_WARN, > CasWebflowConstants.TRANSITION_ID_WARN)); > transitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_ERROR, > getStateIdOnX509Failure(flow))); > > transitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_AUTHENTICATION_FAILURE, > CasWebflowConstants.STATE_ID_HANDLE_AUTHN_FAILURE)); > > transitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_SUCCESS_WITH_WARNINGS, > CasWebflowConstants.STATE_ID_SHOW_AUTHN_WARNING_MSGS)); > > > actionState.getExitActionList().add(createEvaluateAction(CasWebflowConstants.ACTION_ID_CLEAR_WEBFLOW_CREDENTIALS)); > > //Adding Temp ticket webflow transition > > val tempTicketActionState = createActionState(flow, > EVENT_ID_START_TEMP_TICKET, createEvaluateAction("tempTicketCheck")); > val tempTicketTransitionSet = tempTicketActionState.getTransitionSet(); > > tempTicketTransitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_SUCCESS, > > CasWebflowConstants.STATE_ID_CREATE_TICKET_GRANTING_TICKET)); > tempTicketTransitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_WARN, > > CasWebflowConstants.TRANSITION_ID_WARN)); > > tempTicketTransitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_AUTHENTICATION_FAILURE, > CasWebflowConstants.STATE_ID_HANDLE_AUTHN_FAILURE)); > tempTicketTransitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_ERROR, > > getStateIdOnX509Failure(flow))); > > tempTicketTransitionSet.add(createTransition(CasWebflowConstants.TRANSITION_ID_SUCCESS_WITH_WARNINGS, > CasWebflowConstants.STATE_ID_SHOW_AUTHN_WARNING_MSGS)); > > > tempTicketActionState.getExitActionList().add(createEvaluateAction(CasWebflowConstants.ACTION_ID_CLEAR_WEBFLOW_CREDENTIALS)); > > //Injecting the temp ticket webflow before the x509 webflow and to > transition to x509 when a temp ticket doesn't exist > val state = getState(flow, > CasWebflowConstants.STATE_ID_AFTER_INIT_LOGIN_FORM, ActionState.class); > createTransitionForState(state, CasWebflowConstants.TRANSITION_ID_SUCCESS, > EVENT_ID_START_TEMP_TICKET, true); > > val initState = getState(flow, EVENT_ID_START_TEMP_TICKET, ActionState. > class); > createTransitionForState(initState, > CasWebflowConstants.TRANSITION_ID_ERROR, > CasWebflowConstants.STATE_ID_X509_START, true); > } > } > > -- - Website: https://apereo.github.io/cas - List Guidelines: https://goo.gl/1VRrw7 - Contributions: https://goo.gl/mh7qDG --- You received this message because you are subscribed to the Google Groups "CAS Community" group. To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+unsubscr...@apereo.org. To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/fb41ae7a-fb1d-4ad7-b1bd-0ac116ba39f8n%40apereo.org.