All Downloads are FREE. Search and download functionalities are using the official Maven repository.

groovyx.net.http.AuthConfig Maven / Gradle / Ivy

Go to download

A builder-style HTTP client API, including authentication, and extensible handling of common content-types such as JSON and XML. It is built on top of Apache's HttpClient.

There is a newer version: 0.7.1
Show newest version
/*
 * Copyright 2008-2011 Thomas Nichols.  http://blog.thomnichols.org
 *
 * Licensed 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
 *
 *     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.
 *
 * You are receiving this code free of charge, which represents many hours of
 * effort from other individuals and corporations.  As a responsible member
 * of the community, you are encouraged (but not required) to donate any
 * enhancements or improvements back to the community under a similar open
 * source license.  Thank you. -TMN
 */
package groovyx.net.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;

import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.exception.OAuthException;

import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;

/**
 * Encapsulates all configuration related to HTTP authentication methods.
 * @see HTTPBuilder#getAuth()
 *
 * @author Tom Nichols
 */
public class AuthConfig {
    protected HTTPBuilder builder;
    public AuthConfig( HTTPBuilder builder ) {
        this.builder = builder;
    }

    /**
     * Set authentication credentials to be used for the current
     * {@link HTTPBuilder#getUri() default host}.  This method name is a bit of
     * a misnomer, since these credentials will actually work for "digest"
     * authentication as well.
     * @param user
     * @param pass
     */
    public void basic( String user, String pass ) {
        URI uri = ((URIBuilder)builder.getUri()).toURI();
        if ( uri == null ) throw new IllegalStateException( "a default URI must be set" );
        this.basic( uri.getHost(), uri.getPort(), user, pass );
    }

    /**
     * Set authentication credentials to be used for the given host and port.
     * @param host
     * @param port
     * @param user
     * @param pass
     */
    public void basic( String host, int port, String user, String pass ) {
        builder.getClient().getCredentialsProvider().setCredentials(
            new AuthScope( host, port ),
            new UsernamePasswordCredentials( user, pass )
        );
    }

    /**
     * Sets a certificate to be used for SSL authentication.  See
     * {@link Class#getResource(String)} for how to get a URL from a resource
     * on the classpath.
     * @param certURL URL to a JKS keystore where the certificate is stored.
     * @param password password to decrypt the keystore
     */
    public void certificate( String certURL, String password )
            throws GeneralSecurityException, IOException {

        KeyStore keyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
        InputStream jksStream = new URL(certURL).openStream();
        try {
            keyStore.load( jksStream, password.toCharArray() );
        } finally { jksStream.close(); }

        SSLSocketFactory ssl = new SSLSocketFactory(keyStore, password);
        ssl.setHostnameVerifier( SSLSocketFactory.STRICT_HOSTNAME_VERIFIER );

        builder.getClient().getConnectionManager().getSchemeRegistry()
            .register( new Scheme("https", ssl, 443) );
    }

    /**
     * 

OAuth sign all requests. Note that this currently does not * wait for a WWW-Authenticate challenge before sending the * the OAuth header. All requests to all domains will be signed for this * instance.

* *

This assumes you've already generated an accessToken and * secretToken for the site you're targeting. For More information * on how to achieve this, see the * Signpost documentation.

* @since 0.5.1 * @param consumerKey null if you want to unset * OAuth handling and stop signing requests. * @param consumerSecret * @param accessToken * @param secretToken */ public void oauth( String consumerKey, String consumerSecret, String accessToken, String secretToken ) { this.builder.client.removeRequestInterceptorByClass( OAuthSigner.class ); if ( consumerKey != null ) this.builder.client.addRequestInterceptor( new OAuthSigner( consumerKey, consumerSecret, accessToken, secretToken ) ); } /** * This class is used to sign all requests via an {@link HttpRequestInterceptor} * until the context-aware AuthScheme is released in HttpClient 4.1. * @since 0.5.1 */ static class OAuthSigner implements HttpRequestInterceptor { protected OAuthConsumer oauth; public OAuthSigner( String consumerKey, String consumerSecret, String accessToken, String secretToken ) { this.oauth = new CommonsHttpOAuthConsumer( consumerKey, consumerSecret ); oauth.setTokenWithSecret( accessToken, secretToken ); } public void process(HttpRequest request, HttpContext ctx) throws HttpException, IOException { /* The full request URI must be reconstructed between the context and the request URI. * Best we can do until AuthScheme supports HttpContext. See: * https://issues.apache.org/jira/browse/HTTPCLIENT-901 */ try { HttpHost host = (HttpHost) ctx.getAttribute( ExecutionContext.HTTP_TARGET_HOST ); final URI requestURI = new URI( host.toURI() ).resolve( request.getRequestLine().getUri() ); oauth.signpost.http.HttpRequest oAuthRequest = new OAuthRequestAdapter(request, requestURI); this.oauth.sign( oAuthRequest ); } catch ( URISyntaxException ex ) { throw new HttpException( "Error rebuilding request URI", ex ); } catch (OAuthException e) { throw new HttpException( "OAuth signing error", e); } } static class OAuthRequestAdapter implements oauth.signpost.http.HttpRequest { final HttpRequest request; final URI requestURI; OAuthRequestAdapter( HttpRequest request, URI requestURI ) { this.request = request; this.requestURI = requestURI; } public String getRequestUrl() { return requestURI.toString(); } public void setRequestUrl(String url) {/*ignore*/} public Map getAllHeaders() { Map headers = new HashMap(); // FIXME this doesn't account for repeated headers, // which are allowed by the HTTP spec!! for ( Header h : request.getAllHeaders() ) headers.put(h.getName(), h.getValue()); return headers; } public String getContentType() { try { return request.getFirstHeader("content-type").getValue(); } catch ( Exception ex ) { // NPE or ArrayOOBEx return null; } } public String getHeader(String name) { Header h = request.getFirstHeader(name); return h != null ? h.getValue() : null; } public InputStream getMessagePayload() throws IOException { if ( request instanceof HttpEntityEnclosingRequest ) return ((HttpEntityEnclosingRequest)request).getEntity().getContent(); return null; } public String getMethod() { return request.getRequestLine().getMethod(); } public void setHeader(String key, String val) { request.setHeader(key, val); } public Object unwrap() { return request; } }; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy