/* * See LICENSE for licensing and NOTICE for copyright. */ /* * See LICENSE for licensing and NOTICE for copyright. */ package net.shibboleth.idp.cas.flow; import javax.annotation.Nonnull; import net.shibboleth.idp.authn.context.AuthenticationContext; import net.shibboleth.idp.cas.protocol.ProtocolError; import net.shibboleth.idp.cas.session.CASSPSession; import net.shibboleth.idp.cas.ticket.TicketContext; import net.shibboleth.idp.profile.AbstractProfileAction; import net.shibboleth.idp.session.IdPSession; import net.shibboleth.idp.session.SPSession; import net.shibboleth.idp.session.SessionException; import net.shibboleth.idp.session.context.SessionContext; import net.shibboleth.utilities.java.support.annotation.Duration; import net.shibboleth.utilities.java.support.annotation.constraint.Positive; import net.shibboleth.utilities.java.support.logic.Constraint; 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; /** * Updates the {@link IdPSession} with a {@link CASSPSession} that describes the service granted access to and the * ticket that was successfully validated to grant access. Requires the following to be available under the * {@link org.opensaml.profile.context.ProfileRequestContext}: * <ul> * <li>{@link SessionContext}</li> * <li>{@link TicketContext}</li> * </ul> * * @author Marvin S. Addison */ public class UpdateIdPSessionWithSPSessionAction extends AbstractProfileAction { /** Class logger. */ private final Logger log = LoggerFactory.getLogger(UpdateIdPSessionWithSPSessionAction.class); /** Lifetime of sessions to create. */ @Positive @Duration private final long sessionLifetime; /** * Creates a new instance with given parameters. * * @param lifetime lifetime in milliseconds, determines upper bound for expiration of the * {@link CASSPSession} to be created */ public UpdateIdPSessionWithSPSessionAction(@Positive @Duration final long lifetime) { sessionLifetime = Constraint.isGreaterThan(0, lifetime, "Lifetime must be greater than 0"); } @Nonnull @Override protected Event doExecute( final @Nonnull RequestContext springRequestContext, final @Nonnull ProfileRequestContext profileRequestContext) { final TicketContext ticketContext = profileRequestContext.getSubcontext(TicketContext.class); if (ticketContext == null) { log.debug("Cannot create CAS SP session since no TicketContext found."); return ProtocolError.IllegalState.event(this); } final SessionContext sessionContext = profileRequestContext.getSubcontext(SessionContext.class); if (sessionContext == null) { log.debug("Cannot create CAS SP session since no SessionContext found."); return ProtocolError.IllegalState.event(this); } final long now = System.currentTimeMillis(); final SPSession sps = new CASSPSession( ticketContext.getTicket().getService(), now, now + sessionLifetime, ticketContext.getTicket().getId()); log.debug("Created SP session {}", sps); try { sessionContext.getIdPSession().addSPSession(sps); } catch (SessionException e) { log.warn("Failed updating IdP session with CAS SP session: {}", e.getMessage()); return ProtocolError.IllegalState.event(this); } return Events.Success.event(this); } }