org.infoscoop.request.OAuthAuthenticator.java Source code

Java tutorial

Introduction

Here is the source code for org.infoscoop.request.OAuthAuthenticator.java

Source

/* infoScoop OpenSource
 * Copyright (C) 2010 Beacon IT Inc.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/lgpl-3.0-standalone.html>.
 */

package org.infoscoop.request;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.oauth.OAuth;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthException;
import net.oauth.OAuthMessage;
import net.oauth.OAuthServiceProvider;
import net.oauth.client.OAuthClient;
import net.oauth.client.httpclient3.HttpClient3;
import net.oauth.signature.RSA_SHA1;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.infoscoop.dao.OAuthCertificateDAO;
import org.infoscoop.dao.OAuthConsumerDAO;
import org.infoscoop.dao.model.OAuthCertificate;
import org.infoscoop.dao.model.OAuthConsumerProp;
import org.infoscoop.request.ProxyRequest.OAuthConfig;
import org.infoscoop.service.OAuthService;
import org.infoscoop.util.RequestUtil;

public class OAuthAuthenticator implements Authenticator {
    public static final OAuthClient CLIENT = new OAuthClient(new HttpClient3());

    private static String AUTH_CALLBACK_URL = "oauthcallback";

    private static Log log = LogFactory.getLog(OAuthAuthenticator.class);

    private static Map<String, OAuthConsumer> consumers = new HashMap<String, OAuthConsumer>();

    public OAuthAuthenticator() {
    }

    public static OAuthConsumer getConsumer(String gadgetUrl, String serviceName) {
        return consumers.get(gadgetUrl + "\t" + serviceName);
    }

    public void doAuthentication(HttpClient client, ProxyRequest request, HttpMethod method, String uid, String pwd)
            throws ProxyAuthenticationException {
        ProxyRequest.OAuthConfig oauthConfig = request.getOauthConfig();
        try {
            OAuthConsumer consumer = newConsumer(oauthConfig.serviceName, oauthConfig);
            OAuthAccessor accessor = newAccessor(consumer, oauthConfig);
            if (accessor.accessToken == null) {
                getRequestToken(request, accessor);
            }

            Map<String, String> parameters = null;
            String contentType = request.getRequestHeader("Content-Type");
            if (contentType != null && contentType.startsWith("application/x-www-form-urlencoded")
                    && method.getName().equals("POST")) {
                // TODO analyze charset
                String charset = RequestUtil.getCharset(contentType);
                parameters = RequestUtil.parseRequestBody(request.getRequestBody(), charset);
            }
            OAuthMessage message = accessor.newRequestMessage(method.getName(), method.getURI().toString(),
                    parameters != null ? parameters.entrySet() : null);
            String authHeader = message.getAuthorizationHeader(null);
            request.setRequestHeader("Authorization", authHeader);
            // Find the non-OAuth parameters:
        } catch (URISyntaxException e) {
            throw new ProxyAuthenticationException(e);
        } catch (OAuthException e) {
            throw new ProxyAuthenticationException(e);
        } catch (IOException e) {
            throw new ProxyAuthenticationException(e);
        }

    }

    public int getCredentialType() {
        // TODO Auto-generated method stub
        return 3;
    }

    protected OAuthConsumer newConsumer(String name, ProxyRequest.OAuthConfig oauthConfig)
            throws ProxyAuthenticationException {
        OAuthServiceProvider serviceProvider = new OAuthServiceProvider(oauthConfig.requestTokenURL,
                oauthConfig.userAuthorizationURL, oauthConfig.accessTokenURL);

        OAuthConsumerProp consumerProp = OAuthConsumerDAO.newInstance().getConsumer(oauthConfig.getGadgetUrl(),
                name);
        if (consumerProp == null)
            throw new ProxyAuthenticationException(
                    "Consumer key and secret is not set for " + oauthConfig.getGadgetUrl());
        OAuthCertificate certificate = OAuthCertificateDAO.newInstance().get();

        String consumerKey;
        String consumerSecret;
        if ("RSA-SHA1".equals(consumerProp.getSignatureMethod())) {
            consumerKey = certificate.getConsumerKey();
            consumerSecret = null;
        } else {
            consumerKey = consumerProp.getConsumerKey();
            consumerSecret = consumerProp.getConsumerSecret();
        }

        OAuthConsumer consumer = new OAuthConsumer(null, consumerKey, consumerSecret, serviceProvider);
        consumer.setProperty("name", name);
        consumer.setProperty("requestTokenMethod", oauthConfig.requestTokenMethod);
        consumer.setProperty("accessTokenMethod", oauthConfig.accessTokenMethod);

        if (consumerProp.getSignatureMethod() != null)
            consumer.setProperty("oauth_signature_method", consumerProp.getSignatureMethod());

        if ("RSA-SHA1".equals(consumerProp.getSignatureMethod())) {
            if (certificate == null)
                throw new ProxyAuthenticationException("a container's certificate is not set.");
            consumer.setProperty(RSA_SHA1.PRIVATE_KEY, certificate.getPrivateKey());
        }

        consumers.put(oauthConfig.getGadgetUrl() + "\t" + name, consumer);
        return consumer;
    }

    /**
     * Construct an accessor from cookies. The resulting accessor won't
      * necessarily have any tokens.
      */
    private static OAuthAccessor newAccessor(OAuthConsumer consumer, OAuthConfig oauthConfig)
            throws OAuthException {
        OAuthAccessor accessor = new OAuthAccessor(consumer);
        accessor.requestToken = oauthConfig.requestToken;
        accessor.accessToken = oauthConfig.accessToken;
        accessor.tokenSecret = oauthConfig.tokenSecret;
        return accessor;
    }

    private static void getRequestToken(ProxyRequest request, OAuthAccessor accessor)
            throws OAuthException, IOException, URISyntaxException, ProxyAuthenticationException {
        final String consumerName = (String) accessor.consumer.getProperty("name");
        final String callbackURL = getCallbackURL(request, consumerName);
        List<OAuth.Parameter> parameters = OAuth.newList(OAuth.OAUTH_CALLBACK, callbackURL);
        // Google needs to know what you intend to do with the access token:
        Object scope = accessor.consumer.getProperty("request.scope");
        if (scope != null) {
            parameters.add(new OAuth.Parameter("scope", scope.toString()));
        }
        OAuthMessage response = CLIENT.getRequestTokenResponse(accessor,
                (String) accessor.consumer.getProperty("requestTokenMethod"), parameters);
        String gadgetUrl = request.getOauthConfig().getGadgetUrl();
        OAuthService.getHandle().saveOAuthToken(request.getPortalUid(), gadgetUrl, consumerName,
                accessor.requestToken, null, accessor.tokenSecret);
        String authorizationURL = accessor.consumer.serviceProvider.userAuthorizationURL;
        authorizationURL = OAuth.addParameters(authorizationURL //
                , OAuth.OAUTH_TOKEN, accessor.requestToken);
        if (response.getParameter(OAuth.OAUTH_CALLBACK_CONFIRMED) == null) {
            authorizationURL = OAuth.addParameters(authorizationURL //
                    , OAuth.OAUTH_CALLBACK, callbackURL);
        }
        request.putResponseHeader("oauthApprovalUrl", authorizationURL);
        throw new ProxyAuthenticationException("Redirect to authorization url.", false);
    }

    private static String getCallbackURL(ProxyRequest request, String consumerName) throws IOException {
        String gadgetUrl = request.getOauthConfig().getGadgetUrl();
        String hostPrefix = request.getOauthConfig().getHostPrefix();
        URL base = new URL(hostPrefix + "/" + AUTH_CALLBACK_URL + "?__GADGET_URL__=" + gadgetUrl);
        return OAuth.addParameters(base.toExternalForm() //
                , "consumer", consumerName //
        );
    }

}