@Audit( action = "PROXY_GRANTING_TICKET", actionResolverName = "GRANT_PROXY_GRANTING_TICKET_RESOLVER", resourceResolverName = "GRANT_PROXY_GRANTING_TICKET_RESOURCE_RESOLVER") @Timed(name = "GRANT_PROXY_GRANTING_TICKET_TIMER") @Metered(name = "GRANT_PROXY_GRANTING_TICKET_METER") @Counted(name = "GRANT_PROXY_GRANTING_TICKET_COUNTER", monotonic = true) @Transactional(readOnly = false) @Override public TicketGrantingTicket delegateTicketGrantingTicket( final String serviceTicketId, final Credential... credentials) throws AuthenticationException, TicketException { final ServiceTicket serviceTicket = this.serviceTicketRegistry.getTicket(serviceTicketId, ServiceTicket.class); if (serviceTicket == null || serviceTicket.isExpired()) { logger.debug( "ServiceTicket [{}] has expired or cannot be found in the ticket registry", serviceTicketId); throw new InvalidTicketException(serviceTicketId); } final RegisteredService registeredService = this.servicesManager.findServiceBy(serviceTicket.getService()); verifyRegisteredServiceProperties(registeredService, serviceTicket.getService()); if (!registeredService.getProxyPolicy().isAllowedToProxy()) { logger.warn( "ServiceManagement: Service [{}] attempted to proxy, but is not allowed.", serviceTicket.getService().getId()); throw new UnauthorizedProxyingException(); } final Authentication authentication = this.authenticationManager.authenticate(credentials); final String pgtId = this.ticketGrantingTicketUniqueTicketIdGenerator.getNewTicketId( TicketGrantingTicket.PROXY_GRANTING_TICKET_PREFIX); final TicketGrantingTicket proxyGrantingTicket = serviceTicket.grantTicketGrantingTicket( pgtId, authentication, this.ticketGrantingTicketExpirationPolicy); logger.debug( "Generated proxy granting ticket [{}] based off of [{}]", proxyGrantingTicket, serviceTicketId); this.ticketRegistry.addTicket(proxyGrantingTicket); return proxyGrantingTicket; }
@Audit( action = "PROXY_GRANTING_TICKET", actionResolverName = "GRANT_PROXY_GRANTING_TICKET_RESOLVER", resourceResolverName = "GRANT_PROXY_GRANTING_TICKET_RESOURCE_RESOLVER") @Profiled(tag = "GRANT_PROXY_GRANTING_TICKET", logFailuresSeparately = false) @Transactional(readOnly = false) @Override public String delegateTicketGrantingTicket( final String serviceTicketId, final Credential... credentials) throws AuthenticationException, TicketException { Assert.notNull(serviceTicketId, "serviceTicketId cannot be null"); Assert.notNull(credentials, "credentials cannot be null"); final ServiceTicket serviceTicket = this.serviceTicketRegistry.getTicket(serviceTicketId, ServiceTicket.class); if (serviceTicket == null || serviceTicket.isExpired()) { logger.debug( "ServiceTicket [{}] has expired or cannot be found in the ticket registry", serviceTicketId); throw new InvalidTicketException(serviceTicketId); } final RegisteredService registeredService = this.servicesManager.findServiceBy(serviceTicket.getService()); verifyRegisteredServiceProperties(registeredService, serviceTicket.getService()); if (!registeredService.isAllowedToProxy()) { logger.warn( "ServiceManagement: Service [{}] attempted to proxy, but is not allowed.", serviceTicket.getService().getId()); throw new UnauthorizedProxyingException(); } final Authentication authentication = this.authenticationManager.authenticate(credentials); final TicketGrantingTicket ticketGrantingTicket = serviceTicket.grantTicketGrantingTicket( this.ticketGrantingTicketUniqueTicketIdGenerator.getNewTicketId( TicketGrantingTicket.PREFIX), authentication, this.ticketGrantingTicketExpirationPolicy); this.ticketRegistry.addTicket(ticketGrantingTicket); return ticketGrantingTicket.getId(); }
@Audit( action = "SERVICE_TICKET_VALIDATE", actionResolverName = "VALIDATE_SERVICE_TICKET_RESOLVER", resourceResolverName = "VALIDATE_SERVICE_TICKET_RESOURCE_RESOLVER") @Timed(name = "VALIDATE_SERVICE_TICKET_TIMER") @Metered(name = "VALIDATE_SERVICE_TICKET_METER") @Counted(name = "VALIDATE_SERVICE_TICKET_COUNTER", monotonic = true) @Transactional(readOnly = false) @Override public Assertion validateServiceTicket(final String serviceTicketId, final Service service) throws TicketException { final RegisteredService registeredService = this.servicesManager.findServiceBy(service); verifyRegisteredServiceProperties(registeredService, service); final ServiceTicket serviceTicket = this.serviceTicketRegistry.getTicket(serviceTicketId, ServiceTicket.class); if (serviceTicket == null) { logger.info("Service ticket [{}] does not exist.", serviceTicketId); throw new InvalidTicketException(serviceTicketId); } try { synchronized (serviceTicket) { if (serviceTicket.isExpired()) { logger.info("ServiceTicket [{}] has expired.", serviceTicketId); throw new InvalidTicketException(serviceTicketId); } if (!serviceTicket.isValidFor(service)) { logger.error( "Service ticket [{}] with service [{}] does not match supplied service [{}]", serviceTicketId, serviceTicket.getService().getId(), service); throw new UnrecognizableServiceForServiceTicketValidationException( serviceTicket.getService()); } } final TicketGrantingTicket root = serviceTicket.getGrantingTicket().getRoot(); final Authentication authentication = getAuthenticationSatisfiedByPolicy( root, new ServiceContext(serviceTicket.getService(), registeredService)); final Principal principal = authentication.getPrincipal(); final AttributeReleasePolicy attributePolicy = registeredService.getAttributeReleasePolicy(); logger.debug( "Attribute policy [{}] is associated with service [{}]", attributePolicy, registeredService); @SuppressWarnings("unchecked") final Map<String, Object> attributesToRelease = attributePolicy != null ? attributePolicy.getAttributes(principal) : Collections.EMPTY_MAP; final String principalId = registeredService.getUsernameAttributeProvider().resolveUsername(principal, service); final Principal modifiedPrincipal = this.principalFactory.createPrincipal(principalId, attributesToRelease); final AuthenticationBuilder builder = AuthenticationBuilder.newInstance(authentication); builder.setPrincipal(modifiedPrincipal); return new ImmutableAssertion( builder.build(), serviceTicket.getGrantingTicket().getChainedAuthentications(), serviceTicket.getService(), serviceTicket.isFromNewLogin()); } finally { if (serviceTicket.isExpired()) { this.serviceTicketRegistry.deleteTicket(serviceTicketId); } } }
@Override protected ModelAndView handleRequestInternal( final HttpServletRequest request, final HttpServletResponse response) throws Exception { final HttpSession session = request.getSession(); // get cas login service ticket final String serviceTicketId = request.getParameter(OAuthConstants.TICKET); LOGGER.debug("{} : {}", OAuthConstants.TICKET, serviceTicketId); // first time this url is requested the login ticket will be a query parameter if (serviceTicketId != null) { // create the login ticket granting ticket final ServiceTicket serviceTicket = (ServiceTicket) ticketRegistry.getTicket(serviceTicketId); // login service ticket should be valid if (serviceTicket == null || serviceTicket.isExpired()) { LOGGER.error("Service Ticket expired : {}", serviceTicketId); return OAuthUtils.writeTextError( response, OAuthConstants.INVALID_GRANT, HttpStatus.SC_BAD_REQUEST); } final TicketGrantingTicket ticketGrantingTicket = serviceTicket.getGrantingTicket(); // remove login service ticket ticketRegistry.deleteTicket(serviceTicket.getId()); // store the login tgt id in the user's session, used to create service tickets for validation // and // oauth credentials later in the flow. session.setAttribute(OAuthConstants.OAUTH20_LOGIN_TICKET_ID, ticketGrantingTicket.getId()); // redirect back to self, clears the service ticket from the url, allows the url to be // requested multiple // times w/o error return OAuthUtils.redirectTo(request.getRequestURL().toString()); } // get cas login service ticket from the session String ticketGrantingTicketId = (String) session.getAttribute(OAuthConstants.OAUTH20_LOGIN_TICKET_ID); LOGGER.debug("{} : {}", OAuthConstants.TICKET, ticketGrantingTicketId); if (StringUtils.isBlank(ticketGrantingTicketId)) { LOGGER.error("Missing Ticket Granting Ticket"); return OAuthUtils.writeTextError( response, OAuthConstants.INVALID_GRANT, HttpStatus.SC_BAD_REQUEST); } // verify the login ticket granting ticket is still valid TicketGrantingTicket ticketGrantingTicket = (TicketGrantingTicket) ticketRegistry.getTicket(ticketGrantingTicketId); if (ticketGrantingTicket == null || ticketGrantingTicket.isExpired()) { LOGGER.error("Ticket Granting Ticket expired : {}", ticketGrantingTicketId); return OAuthUtils.writeTextError( response, OAuthConstants.INVALID_GRANT, HttpStatus.SC_BAD_REQUEST); } String callbackUrl = request .getRequestURL() .toString() .replace( "/" + OAuthConstants.CALLBACK_AUTHORIZE_URL, "/" + OAuthConstants.CALLBACK_AUTHORIZE_ACTION_URL); LOGGER.debug("{} : {}", OAuthConstants.CALLBACK_AUTHORIZE_ACTION_URL, callbackUrl); String allowCallbackUrl = OAuthUtils.addParameter( callbackUrl, OAuthConstants.OAUTH20_APPROVAL_PROMPT_ACTION, OAuthConstants.OAUTH20_APPROVAL_PROMPT_ACTION_ALLOW); final Map<String, Object> model = new HashMap<>(); model.put("callbackUrl", callbackUrl); final Boolean bypassApprovalPrompt = (Boolean) session.getAttribute(OAuthConstants.BYPASS_APPROVAL_PROMPT); LOGGER.debug("bypassApprovalPrompt : {}", bypassApprovalPrompt); if (bypassApprovalPrompt != null && bypassApprovalPrompt) { return OAuthUtils.redirectTo(allowCallbackUrl); } final String clientId = (String) session.getAttribute(OAuthConstants.OAUTH20_CLIENT_ID); LOGGER.debug("{} : {}", OAuthConstants.CLIENT_ID, clientId); final Principal loginPrincipal = ticketGrantingTicket.getAuthentication().getPrincipal(); final String approvalPrompt = (String) session.getAttribute(OAuthConstants.OAUTH20_APPROVAL_PROMPT); LOGGER.debug("approvalPrompt : {}", approvalPrompt); if (StringUtils.isBlank(approvalPrompt) || !approvalPrompt.equalsIgnoreCase(OAuthConstants.APPROVAL_PROMPT_FORCE)) { final TicketGrantingTicket refreshToken = OAuthTokenUtils.getRefreshToken(centralAuthenticationService, clientId, loginPrincipal); if (refreshToken != null) { return OAuthUtils.redirectTo(allowCallbackUrl); } } // retrieve service name from session final String serviceName = (String) session.getAttribute(OAuthConstants.OAUTH20_SERVICE_NAME); LOGGER.debug("serviceName : {}", serviceName); model.put("serviceName", serviceName); return new ModelAndView(OAuthConstants.CONFIRM_VIEW, model); }