001    /*
002     * Copyright 2003-2008 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     *
016     * You are receiving this code free of charge, which represents many hours of
017     * effort from other individuals and corporations.  As a responsible member 
018     * of the community, you are asked (but not required) to donate any 
019     * enhancements or improvements back to the community under a similar open 
020     * source license.  Thank you. -TMN
021     */
022    package groovyx.net.http;
023    
024    import java.io.IOException;
025    import java.io.InputStream;
026    import java.net.MalformedURLException;
027    import java.net.URL;
028    import java.security.GeneralSecurityException;
029    import java.security.KeyStore;
030    
031    import org.apache.http.auth.AuthScope;
032    import org.apache.http.auth.UsernamePasswordCredentials;
033    import org.apache.http.conn.scheme.Scheme;
034    import org.apache.http.conn.ssl.SSLSocketFactory;
035    
036    /**
037     * Encapsulates all configuration related to HTTP authentication methods.
038     * @see HTTPBuilder#getAuth()
039     * 
040     * @author <a href='mailto:tnichols@enernoc.com'>Tom Nichols</a>
041     */
042    public class AuthConfig {
043            protected HTTPBuilder builder;
044            public AuthConfig( HTTPBuilder builder ) {
045                    this.builder = builder;
046            }
047            
048            /**
049             * Set authentication credentials to be used for the current 
050             * {@link HTTPBuilder#getURL() default host}.  This method name is a bit of 
051             * a misnomer, since these credentials will actually work for "digest" 
052             * authentication as well.
053             * @param user
054             * @param pass
055             */
056            public void basic( String user, String pass ) {
057                    URL url = (URL)builder.getURL();
058                    if ( url == null ) throw new IllegalStateException( "a default URL must be set" );
059                    this.basic( url.getHost(), url.getPort(), user, pass );
060            }
061            
062            /**
063             * Set authentication credentials to be used for the given host and port. 
064             * @param host
065             * @param port
066             * @param user
067             * @param pass
068             */
069            public void basic( String host, int port, String user, String pass ) {
070                    builder.getClient().getCredentialsProvider().setCredentials( 
071                            new AuthScope( host, port ),
072                            new UsernamePasswordCredentials( user, pass )
073                    );
074            }
075            
076            /**
077             * Sets a certificate to be used for SSL authentication.  
078             * @param certURL URL to a JKS keystore where the certificate is stored
079             * @param password password to decrypt the keystore
080             */
081            public void certificate( String certURL, String password ) 
082                            throws GeneralSecurityException, MalformedURLException, IOException {
083                    
084                    KeyStore keyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
085            InputStream jksStream = new URL(certURL).openStream();
086            try {
087                    keyStore.load( jksStream, password.toCharArray() );
088            } finally { jksStream.close(); }
089    
090            SSLSocketFactory ssl = new SSLSocketFactory(keyStore, password);
091            ssl.setHostnameVerifier( SSLSocketFactory.STRICT_HOSTNAME_VERIFIER );
092            
093            builder.getClient().getConnectionManager().getSchemeRegistry()
094                    .register( new Scheme("https", ssl, 443) );
095            }
096    }