/** * Handle the request. Specially, abides by the default behavior specified in the {@link * org.jasig.cas.web.ServiceValidateController} and then, invokes the {@link #getCommandClass()} * method to delegate the task of spec validation. * * @param request request object * @param response response object * @return A {@link ModelAndView} object pointing to either {@link #setSuccessView(String)} or * {@link #setFailureView(String)} * @throws Exception In case the authentication method cannot be retrieved by the binder from the * incoming request. */ @Override protected final ModelAndView handleRequestInternal( final HttpServletRequest request, final HttpServletResponse response) throws Exception { final WebApplicationService service = this.argumentExtractor.extractService(request); final String serviceTicketId = service != null ? service.getArtifactId() : null; final String authnMethod = getAuthenticationMethodFromRequest(request); if (service == null || serviceTicketId == null) { logger.debug( String.format( "Could not process request; Service: %s, Service Ticket Id: %s", service, serviceTicketId)); return generateErrorView("INVALID_REQUEST", "INVALID_REQUEST", authnMethod, null); } try { final Credential serviceCredentials = getServiceCredentialsFromRequest(request); String proxyGrantingTicketId = null; if (serviceCredentials != null) { try { proxyGrantingTicketId = this.centralAuthenticationService.delegateTicketGrantingTicket( serviceTicketId, serviceCredentials); } catch (final TicketException e) { logger.error("TicketException generating ticket for: " + serviceCredentials, e); } } final Assertion assertion = this.centralAuthenticationService.validateServiceTicket(serviceTicketId, service); final AbstractMultiFactorAuthenticationProtocolValidationSpecification validationSpecification = this.getCommandClass(); final ServletRequestDataBinder binder = new ServletRequestDataBinder(validationSpecification, "validationSpecification"); initBinder(request, binder); binder.bind(request); /** * The binder does not support field aliases. This means that the request parameter names must * exactly match the validation spec fields, or the match fails. Since the validation request * per the modified protocol will use 'authn_method', we could either create a matching field * inside the validation object, create a custom data binder object that does the conversion, * or simply bind the parameter manually. * * <p>This implementation opts for the latter choice. */ validationSpecification.setAuthenticationMethod(authnMethod); try { if (!validationSpecification.isSatisfiedBy(assertion)) { logger.debug( "ServiceTicket [" + serviceTicketId + "] does not satisfy validation specification."); return generateErrorView("INVALID_TICKET", "INVALID_TICKET_SPEC", authnMethod, null); } } catch (final UnrecognizedMultiFactorAuthenticationMethodException e) { logger.debug(e.getMessage(), e); return generateErrorView( e.getCode(), e.getMessage(), authnMethod, new Object[] {e.getAuthenticationMethod()}); } catch (final UnacceptableMultiFactorAuthenticationMethodException e) { logger.debug(e.getMessage(), e); return generateErrorView( e.getCode(), e.getMessage(), authnMethod, new Object[] {serviceTicketId, e.getAuthenticationMethod()}); } onSuccessfulValidation(serviceTicketId, assertion); final ModelAndView success = new ModelAndView(this.successView); success.addObject(MODEL_ASSERTION, assertion); if (serviceCredentials != null && proxyGrantingTicketId != null) { final String proxyIou = this.proxyHandler.handle(serviceCredentials, proxyGrantingTicketId); success.addObject(MODEL_PROXY_GRANTING_TICKET_IOU, proxyIou); } final String authnMethods = MultiFactorUtils.getFulfilledAuthenticationMethodsAsString(assertion); if (StringUtils.isNotBlank(authnMethods)) { success.addObject(MODEL_AUTHN_METHOD, authnMethods); } logger.debug(String.format("Successfully validated service ticket: %s", serviceTicketId)); return success; } catch (final TicketValidationException e) { return generateErrorView( e.getCode(), e.getCode(), authnMethod, new Object[] {serviceTicketId, e.getOriginalService().getId(), service.getId()}); } catch (final TicketException te) { return generateErrorView( te.getCode(), te.getCode(), authnMethod, new Object[] {serviceTicketId}); } catch (final UnauthorizedServiceException e) { return generateErrorView(e.getMessage(), e.getMessage(), authnMethod, null); } }
protected final ModelAndView handleRequestInternal( final HttpServletRequest request, final HttpServletResponse response) throws Exception { final WebApplicationService service = this.argumentExtractor.extractService(request); final String serviceTicketId = service != null ? service.getArtifactId() : null; if (service == null || serviceTicketId == null) { logger.debug( String.format( "Could not process request; Service: %s, Service Ticket Id: %s", service, serviceTicketId)); return generateErrorView("INVALID_REQUEST", "INVALID_REQUEST", null); } try { final Credentials serviceCredentials = getServiceCredentialsFromRequest(request); String proxyGrantingTicketId = null; // XXX should be able to validate AND THEN use if (serviceCredentials != null) { try { proxyGrantingTicketId = this.centralAuthenticationService.delegateTicketGrantingTicket( serviceTicketId, serviceCredentials); } catch (final TicketException e) { logger.error("TicketException generating ticket for: " + serviceCredentials, e); } } final Assertion assertion = this.centralAuthenticationService.validateServiceTicket(serviceTicketId, service); final ValidationSpecification validationSpecification = this.getCommandClass(); final ServletRequestDataBinder binder = new ServletRequestDataBinder(validationSpecification, "validationSpecification"); initBinder(request, binder); binder.bind(request); if (!validationSpecification.isSatisfiedBy(assertion)) { if (logger.isDebugEnabled()) { logger.debug( "ServiceTicket [" + serviceTicketId + "] does not satisfy validation specification."); } return generateErrorView("INVALID_TICKET", "INVALID_TICKET_SPEC", null); } onSuccessfulValidation(serviceTicketId, assertion); final ModelAndView success = new ModelAndView(this.successView); success.addObject(MODEL_ASSERTION, assertion); if (serviceCredentials != null && proxyGrantingTicketId != null) { final String proxyIou = this.proxyHandler.handle(serviceCredentials, proxyGrantingTicketId); success.addObject(MODEL_PROXY_GRANTING_TICKET_IOU, proxyIou); } if (logger.isDebugEnabled()) { logger.debug( String.format( "Successfully validated service ticket [%s] for service [%s]", serviceTicketId, service.getId())); } return success; } catch (final TicketValidationException e) { return generateErrorView( e.getCode(), e.getCode(), new Object[] {serviceTicketId, e.getOriginalService().getId(), service.getId()}); } catch (final TicketException te) { return generateErrorView(te.getCode(), te.getCode(), new Object[] {serviceTicketId}); } catch (final UnauthorizedServiceException e) { return generateErrorView(e.getMessage(), e.getMessage(), null); } }