/* * See LICENSE for licensing and NOTICE for copyright. */ package net.shibboleth.idp.cas.flow; import javax.annotation.Nonnull; import net.shibboleth.idp.cas.protocol.ServiceTicketRequest; import net.shibboleth.idp.profile.AbstractProfileAction; import net.shibboleth.idp.session.IdPSession; import net.shibboleth.idp.session.SessionException; import net.shibboleth.idp.session.context.SessionContext; import org.opensaml.profile.context.ProfileRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; /** * Determines whether authentication is required by examining both SSO session state and CAS * service ticket request message. Returns one of the following events: * * <ul> * <li>{@link Events#GatewayRequested gatewayRequested} - Authentication not required since no ticket is requested.</li> * <li>{@link Events#RenewRequested renewRequested} - Authentication required regardless of existing session.</li> * <li>{@link Events#SessionFound sessionFound} - Authentication not required since session already exists.</li> * <li>{@link Events#SessionNotFound sessionNotFound} - Authentication required since no active session exists.</li> * </ul> * * @author Marvin S. Addison */ public class CheckAuthenticationRequiredAction extends AbstractProfileAction<ServiceTicketRequest, Object> { /** Class logger. */ private final Logger log = LoggerFactory.getLogger(CheckAuthenticationRequiredAction.class); /** {@inheritDoc} */ @Nonnull @Override protected Event doExecute( final @Nonnull RequestContext springRequestContext, final @Nonnull ProfileRequestContext<ServiceTicketRequest, Object> profileRequestContext) { final ServiceTicketRequest request = FlowStateSupport.getServiceTicketRequest(springRequestContext); // Per http://www.jasig.org/cas/protocol section 2.1.1 // It is RECOMMENDED that renew supersede gateway if (request.isRenew()) { return new Event(this, Events.RenewRequested.id()); } if (request.isGateway()) { return new Event(this, Events.GatewayRequested.id()); } final SessionContext sessionCtx = profileRequestContext.getSubcontext(SessionContext.class, false); Events result; if (sessionCtx != null) { final IdPSession session = sessionCtx.getIdPSession(); if (session != null) { log.debug("Found session ID {}", session.getId()); try { // Timeout check updates session lastActivityInstant field if (session.checkTimeout()) { result = Events.SessionFound; } else { result = Events.SessionNotFound; } } catch (SessionException e) { log.debug("Error performing session timeout check. Assuming session has expired.", e); result = Events.SessionNotFound; } } else { log.debug("Session not found."); result = Events.SessionNotFound; } } else { log.debug("Session context not found."); result = Events.SessionNotFound; } return result.event(this); } }