/* * See LICENSE for licensing and NOTICE for copyright. */ package net.shibboleth.idp.cas.flow; import javax.annotation.Nonnull; import net.shibboleth.idp.cas.protocol.ProtocolError; import net.shibboleth.idp.cas.protocol.ServiceTicketRequest; import net.shibboleth.idp.cas.protocol.ServiceTicketResponse; import net.shibboleth.idp.cas.ticket.ServiceTicket; import net.shibboleth.idp.cas.ticket.TicketContext; import net.shibboleth.idp.cas.ticket.TicketService; import net.shibboleth.idp.profile.AbstractProfileAction; import net.shibboleth.idp.profile.ActionSupport; import net.shibboleth.idp.session.context.SessionContext; import net.shibboleth.utilities.java.support.logic.Constraint; import org.opensaml.profile.action.EventIds; import org.opensaml.profile.context.ProfileRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; /** * Generates and stores a CAS protocol service ticket. Possible outcomes: * <ul> * <li>{@link net.shibboleth.idp.cas.flow.Events#Success success}</li> * <li>{@link net.shibboleth.idp.cas.protocol.ProtocolError#TicketCreationError ticketCreationError}</li> * </ul> * In the success case a {@link ServiceTicketResponse} message is created and stored * as request scope parameter under the key {@value FlowStateSupport#SERVICE_TICKET_RESPONSE_KEY}. * * @author Marvin S. Addison */ public class GrantServiceTicketAction extends AbstractProfileAction<ServiceTicketRequest, ServiceTicketRequest> { /** Class logger. */ private final Logger log = LoggerFactory.getLogger(GrantServiceTicketAction.class); /** Manages CAS tickets. */ @Nonnull private final TicketService ticketService; /** * Creates a new instance. * * @param ticketService Ticket service component. */ public GrantServiceTicketAction(@Nonnull TicketService ticketService) { this.ticketService = Constraint.isNotNull(ticketService, "TicketService cannot be null"); } /** {@inheritDoc} */ @Nonnull @Override protected Event doExecute( final @Nonnull RequestContext springRequestContext, final @Nonnull ProfileRequestContext<ServiceTicketRequest, ServiceTicketRequest> profileRequestContext) { final ServiceTicketRequest request = FlowStateSupport.getServiceTicketRequest(springRequestContext); final SessionContext sessionCtx = profileRequestContext.getSubcontext(SessionContext.class, false); if (sessionCtx == null || sessionCtx.getIdPSession() == null) { log.info("Cannot locate IdP session"); return ProtocolError.IllegalState.event(this); } final ServiceTicket ticket; try { log.debug("Granting service ticket for {}", request.getService()); ticket = ticketService.createServiceTicket( sessionCtx.getIdPSession().getId(), request.getService(), request.isRenew()); } catch (RuntimeException e) { log.error("Failed granting service ticket due to error.", e); return ProtocolError.TicketCreationError.event(this); } log.info("Granted service ticket for {}", request.getService()); final ServiceTicketResponse response = new ServiceTicketResponse(request.getService(), ticket.getId()); if (request.isSaml()) { response.setSaml(true); } FlowStateSupport.setServiceTicketResponse(springRequestContext, response); return Events.Success.event(this); } }