/* * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at the following location: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.cas.authentication.handler.support; import java.security.GeneralSecurityException; import org.jasig.cas.authentication.AbstractAuthenticationHandler; import org.jasig.cas.authentication.Credential; import org.jasig.cas.authentication.HandlerResult; import org.jasig.cas.authentication.HttpBasedServiceCredential; import org.jasig.cas.authentication.principal.SimplePrincipal; import org.jasig.cas.util.HttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.security.auth.login.FailedLoginException; import javax.validation.constraints.NotNull; /** * Class to validate the credential presented by communicating with the web * server and checking the certificate that is returned against the hostname, * etc. * <p> * This class is concerned with ensuring that the protocol is HTTPS and that a * response is returned. The SSL handshake that occurs automatically by opening * a connection does the heavy process of authenticating. * * @author Scott Battaglia * @since 3.0 */ public final class HttpBasedServiceCredentialsAuthenticationHandler extends AbstractAuthenticationHandler { /** The string representing the HTTPS protocol. */ private static final String PROTOCOL_HTTPS = "https"; /** Boolean variable denoting whether secure connection is required or not. */ private boolean requireSecure = true; /** Log instance. */ private final Logger logger = LoggerFactory.getLogger(getClass()); /** Instance of Apache Commons HttpClient. */ @NotNull private HttpClient httpClient; public HandlerResult authenticate(final Credential credential) throws GeneralSecurityException { final HttpBasedServiceCredential httpCredential = (HttpBasedServiceCredential) credential; if (this.requireSecure && !httpCredential.getCallbackUrl().getProtocol().equals(PROTOCOL_HTTPS)) { logger.debug("Authentication failed because url was not secure."); throw new FailedLoginException(httpCredential.getCallbackUrl() + " is not an HTTPS endpoint as required."); } logger.debug("Attempting to authenticate {}", httpCredential); if (!this.httpClient.isValidEndPoint(httpCredential.getCallbackUrl())) { throw new FailedLoginException( httpCredential.getCallbackUrl() + " sent an unacceptable response status code"); } return new HandlerResult(this, httpCredential, new SimplePrincipal(httpCredential.getId())); } /** * @return true if the credential provided are not null and the credential * are a subclass of (or equal to) HttpBasedServiceCredential. */ public boolean supports(final Credential credential) { return credential instanceof HttpBasedServiceCredential; } /** * Sets the HttpClient which will do all of the connection stuff. * @param httpClient http client instance to use **/ public void setHttpClient(final HttpClient httpClient) { this.httpClient = httpClient; } /** * Set whether a secure url is required or not. * * @param requireSecure true if its required, false if not. Default is true. */ public void setRequireSecure(final boolean requireSecure) { this.requireSecure = requireSecure; } }