package org.apereo.cas.support.oauth.web.endpoints; import org.apereo.cas.authentication.principal.PrincipalFactory; import org.apereo.cas.authentication.principal.ServiceFactory; import org.apereo.cas.authentication.principal.WebApplicationService; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.services.ServicesManager; import org.apereo.cas.support.oauth.profile.OAuth20ProfileScopeToAttributesFilter; import org.apereo.cas.support.oauth.validator.OAuth20Validator; import org.apereo.cas.support.oauth.web.response.accesstoken.ext.AccessTokenRequestDataHolder; import org.apereo.cas.ticket.OAuthToken; import org.apereo.cas.ticket.TicketGrantingTicket; import org.apereo.cas.ticket.TicketState; import org.apereo.cas.ticket.accesstoken.AccessToken; import org.apereo.cas.ticket.accesstoken.AccessTokenFactory; import org.apereo.cas.ticket.code.OAuthCode; import org.apereo.cas.ticket.registry.TicketRegistry; import org.apereo.cas.web.support.CookieRetrievingCookieGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; /** * This controller is the base controller for wrapping OAuth protocol in CAS. * * @author Jerome Leleu * @since 3.5.0 */ @Controller public abstract class BaseOAuth20Controller { private static final Logger LOGGER = LoggerFactory.getLogger(BaseOAuth20Controller.class); /** * Collection of CAS settings. */ protected final CasConfigurationProperties casProperties; /** * Convert profile scopes to attributes. */ protected final OAuth20ProfileScopeToAttributesFilter scopeToAttributesFilter; /** * Services manager. */ protected final ServicesManager servicesManager; /** * Cookie retriever. */ protected final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator; /** * The Ticket registry. */ protected final TicketRegistry ticketRegistry; /** * The Validator. */ protected final OAuth20Validator validator; /** * The Access token factory. */ protected final AccessTokenFactory accessTokenFactory; /** * The Principal factory. */ protected final PrincipalFactory principalFactory; /** * The Web application service service factory. */ protected final ServiceFactory<WebApplicationService> webApplicationServiceServiceFactory; /** * Instantiates a new Base o auth 20 controller. * * @param servicesManager the services manager * @param ticketRegistry the ticket registry * @param validator the validator * @param accessTokenFactory the access token factory * @param principalFactory the principal factory * @param webApplicationServiceServiceFactory the web application service service factory * @param scopeToAttributesFilter the scope to attributes filter * @param casProperties the cas properties * @param ticketGrantingTicketCookieGenerator the ticket granting ticket cookie generator */ public BaseOAuth20Controller(final ServicesManager servicesManager, final TicketRegistry ticketRegistry, final OAuth20Validator validator, final AccessTokenFactory accessTokenFactory, final PrincipalFactory principalFactory, final ServiceFactory<WebApplicationService> webApplicationServiceServiceFactory, final OAuth20ProfileScopeToAttributesFilter scopeToAttributesFilter, final CasConfigurationProperties casProperties, final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator) { this.servicesManager = servicesManager; this.ticketRegistry = ticketRegistry; this.validator = validator; this.accessTokenFactory = accessTokenFactory; this.principalFactory = principalFactory; this.webApplicationServiceServiceFactory = webApplicationServiceServiceFactory; this.casProperties = casProperties; this.scopeToAttributesFilter = scopeToAttributesFilter; this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator; } /** * Generate an access token from a service and authentication. * * @param responseHolder the response holder * @return an access token */ protected AccessToken generateAccessToken(final AccessTokenRequestDataHolder responseHolder) { LOGGER.debug("Creating refresh token for [{}]", responseHolder.getService()); final AccessToken accessToken = this.accessTokenFactory.create(responseHolder.getService(), responseHolder.getAuthentication(), responseHolder.getTicketGrantingTicket()); LOGGER.debug("Creating access token [{}]", accessToken); addTicketToRegistry(accessToken, responseHolder.getTicketGrantingTicket()); LOGGER.debug("Added access token [{}] to registry", accessToken); if (responseHolder.getToken() instanceof OAuthCode) { final TicketState codeState = TicketState.class.cast(responseHolder.getToken()); codeState.update(); if (responseHolder.getToken().isExpired()) { this.ticketRegistry.deleteTicket(responseHolder.getToken().getId()); } else { this.ticketRegistry.updateTicket(responseHolder.getToken()); } this.ticketRegistry.updateTicket(responseHolder.getTicketGrantingTicket()); } return accessToken; } /** * Add ticket to registry. * * @param ticket the ticket * @param ticketGrantingTicket the ticket granting ticket */ protected void addTicketToRegistry(final OAuthToken ticket, final TicketGrantingTicket ticketGrantingTicket) { LOGGER.debug("Adding OAuth ticket [{}] to registry", ticket); this.ticketRegistry.addTicket(ticket); if (ticketGrantingTicket != null) { LOGGER.debug("Updating ticket-granting ticket [{}]", ticketGrantingTicket); this.ticketRegistry.updateTicket(ticketGrantingTicket); } } }