fr.paris.lutece.plugins.mylutece.modules.oauth.authentication.OAuthAuthentication.java Source code

Java tutorial

Introduction

Here is the source code for fr.paris.lutece.plugins.mylutece.modules.oauth.authentication.OAuthAuthentication.java

Source

/*
 * Copyright (c) 2002-2014, Mairie de Paris
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice
 *     and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright notice
 *     and the following disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *
 *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * License 1.0
 */
package fr.paris.lutece.plugins.mylutece.modules.oauth.authentication;

import fr.paris.lutece.plugins.mylutece.authentication.PortalAuthentication;
import fr.paris.lutece.plugins.mylutece.modules.oauth.service.OAuthPlugin;
import fr.paris.lutece.portal.service.security.LoginRedirectException;
import fr.paris.lutece.portal.service.security.LuteceUser;
import fr.paris.lutece.portal.service.util.AppException;
import fr.paris.lutece.portal.service.util.AppLogService;
import fr.paris.lutece.portal.service.util.AppPathService;
import fr.paris.lutece.portal.service.util.AppPropertiesService;
import fr.paris.lutece.portal.web.LocalVariables;

import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;

import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;

import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import oauth.signpost.exception.OAuthNotAuthorizedException;

import org.apache.commons.lang.StringUtils;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.IOException;

import javax.security.auth.login.LoginException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * OAuthAuthentication. (version 1.0a). <br>
 * Uses <strong>httpAccess.*</strong> properties to perform HTTP requests.
 * @see <a href="http://oauth.net/">oauth.net</a>
 */
public class OAuthAuthentication extends PortalAuthentication {
    private static final String PROPERTY_PROXY_HOST = "httpAccess.proxyHost";
    private static final String PROPERTY_PROXY_PORT = "httpAccess.proxyPort";
    private static final String PROPERTY_PROXY_USERNAME = "httpAccess.proxyUserName";
    private static final String PROPERTY_PROXY_PASSWORD = "httpAccess.proxyPassword";
    private static final String PROPERTY_DOMAIN_NAME = "httpAccess.domainName";
    private static final String PARAMETER_OAUTH_VERIFIER = OAuth.OAUTH_VERIFIER;
    private static final String PARAMETER_OAUTH_TOKEN = OAuth.OAUTH_TOKEN;
    private static final String CONSTANT_CALLBACK_URL = "jsp/site/plugins/mylutece/modules/oauth/Redirect.jsp?auth_provider=";

    /**
     * A cookie will be created for a token request, to store the token secret, since Token Secret is not passed through callback url.
     */
    private static final String CONSTANT_COOKIE_TOKEN_SECRET = "oauth_token_secret";
    private String _strAuthServiceName;
    private String _strName;
    private String _strIconUrl;
    private String _strRequestTokenEndpointUrl;
    private String _strAccessTokenEndpointUrl;
    private String _strAuthorizeWebsiteUrl;
    private String _strConsumerKey;
    private String _strConsumerSecret;
    private String _strCredentialUrl;
    private String _strCredentialFormat;

    /**
     *
     *{@inheritDoc}
     */
    public LuteceUser getAnonymousUser() {
        return new OAuthUser(LuteceUser.ANONYMOUS_USERNAME, this);
    }

    /**
     *
     *{@inheritDoc}
     */
    public String getAuthServiceName() {
        return _strAuthServiceName;
    }

    /**
     *
     *{@inheritDoc}
     */
    public String getAuthType(HttpServletRequest request) {
        return HttpServletRequest.BASIC_AUTH;
    }

    /**
     *
     *{@inheritDoc}
     */
    public String getIconUrl() {
        return _strIconUrl;
    }

    /**
     *
     *{@inheritDoc}
     */
    public String getName() {
        return _strName;
    }

    /**
     *
     *{@inheritDoc}
     */
    public String getPluginName() {
        return OAuthPlugin.PLUGIN_NAME;
    }

    /**
     *
     *{@inheritDoc}
     */
    public boolean isUserInRole(LuteceUser user, HttpServletRequest request, String strRole) {
        return false;
    }

    /**
     * Builds a new {@link HttpClient}
     * @return new HttpClient
     */
    private HttpClient getHttpClient() {
        DefaultHttpClient client = new DefaultHttpClient();

        String strUserName = AppPropertiesService.getProperty(PROPERTY_PROXY_USERNAME);
        String strPassword = AppPropertiesService.getProperty(PROPERTY_PROXY_PASSWORD);
        String strDomainName = AppPropertiesService.getProperty(PROPERTY_DOMAIN_NAME);

        if (StringUtils.isNotBlank(strUserName) && StringUtils.isNotBlank(strPassword)) {
            // at least Userpasswordcredz
            Credentials creds;

            if (StringUtils.isBlank(strDomainName)) {
                creds = new UsernamePasswordCredentials(strUserName, strPassword);
            } else {
                creds = new NTCredentials(strUserName, strPassword, "", strDomainName);
            }

            CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(AuthScope.ANY, creds);
            client.setCredentialsProvider(credsProvider);

            HttpHost proxy = new HttpHost(AppPropertiesService.getProperty(PROPERTY_PROXY_HOST),
                    AppPropertiesService.getPropertyInt(PROPERTY_PROXY_PORT, 8080));
            client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
        }

        return client;
    }

    /**
     * Gets the request token url. Builds the provider. CallBack url is {@link #CONSTANT_CALLBACK_URL}
     * @param request the request
     * @param consumer the consumer
     * @return the redirect url
     * @throws OAuthMessageSignerException if occurs
     * @throws OAuthNotAuthorizedException if occurs
     * @throws OAuthExpectationFailedException if occurs
     * @throws OAuthCommunicationException if occurs
     */
    private String getRedirectUrl(HttpServletRequest request, OAuthConsumer consumer)
            throws OAuthMessageSignerException, OAuthNotAuthorizedException, OAuthExpectationFailedException,
            OAuthCommunicationException {
        return getProvider().retrieveRequestToken(consumer,
                AppPathService.getBaseUrl(request) + CONSTANT_CALLBACK_URL + this.getName());
    }

    /**
     * Builds a provider
     * @return the provider
     */
    private OAuthProvider getProvider() {
        CommonsHttpOAuthProvider provider = new CommonsHttpOAuthProvider(getRequestTokenEndpointUrl(),
                getAccessTokenEndpointUrl(), getAuthorizeWebsiteUrl());

        provider.setHttpClient(getHttpClient());

        return provider;
    }

    /**
     * Buids a consumer
     * @return the {@link OAuthConsumer}
     */
    private OAuthConsumer getConsumer() {
        return new CommonsHttpOAuthConsumer(getConsumerKey(), getConsumerSecret());
    }

    /**
     *
     *{@inheritDoc}
     */
    @Override
    public boolean isDelegatedAuthentication() {
        return true;
    }

    /**
     *
     *{@inheritDoc}
     */
    public LuteceUser login(String strUserName, String strUserPassword, HttpServletRequest request)
            throws LoginException, LoginRedirectException {
        OAuthConsumer consumer = getConsumer();

        try {
            // FIXME : version specific
            String url = getRedirectUrl(request, consumer);

            if (AppLogService.isDebugEnabled()) {
                AppLogService.debug("Url to visit : " + url);
                AppLogService.debug("Token secret : " + consumer.getTokenSecret());
            }

            // create cookie to store token secret
            createCookie(CONSTANT_COOKIE_TOKEN_SECRET, consumer.getTokenSecret());

            throw new LoginRedirectException(url);
        } catch (OAuthMessageSignerException e) {
            AppLogService.error(e.getMessage(), e);
        } catch (OAuthExpectationFailedException e) {
            AppLogService.error(e.getMessage(), e);
        } catch (OAuthCommunicationException e) {
            AppLogService.error(e.getMessage(), e);
        } catch (OAuthNotAuthorizedException e) {
            AppLogService.error(e.getMessage(), e);
        }

        return null;
    }

    /**
     * Gets the user
     * @param request the reuqest
     * @return the user found.
     */
    public OAuthUser getUser(HttpServletRequest request) {
        String strToken = request.getParameter(PARAMETER_OAUTH_TOKEN);
        String strVerifier = request.getParameter(PARAMETER_OAUTH_VERIFIER);

        if (StringUtils.isNotBlank(strToken) && StringUtils.isNotBlank(strVerifier)) {
            // FIXME : version specific
            Cookie cookie = findCookie(request, CONSTANT_COOKIE_TOKEN_SECRET);

            OAuthConsumer consumer = getConsumer();
            consumer.setTokenWithSecret(strToken, cookie.getValue());

            try {
                OAuthProvider provider = getProvider();
                provider.setOAuth10a(true);
                provider.retrieveAccessToken(consumer, strVerifier);

                // FIXME :  username.
                OAuthUser user = new OAuthUser(this.getName(), this);
                user.setToken(strToken);
                user.setVerifier(strVerifier);
                user.setTokenSecret(cookie.getValue());

                // get user infos
                if (StringUtils.isNotBlank(getCredentialUrl())) {
                    HttpGet getMethod = new HttpGet(getCredentialUrl());

                    consumer.sign(getMethod);

                    HttpResponse httpResponse = getHttpClient().execute(getMethod);

                    int nStatusCode = httpResponse.getStatusLine().getStatusCode();

                    if (nStatusCode == HttpStatus.SC_OK) {
                        OAuthCredentialsRetrieverUtils.doRetrieveUserInfo(httpResponse, user,
                                getCredentialFormat());
                    } else {
                        AppLogService.error(httpResponse.getStatusLine());
                        throw new AppException("Unable to find user infos : " + httpResponse.getStatusLine());
                    }
                }

                return user;
            } catch (OAuthMessageSignerException e) {
                AppLogService.error(e.getMessage(), e);
            } catch (OAuthNotAuthorizedException e) {
                AppLogService.error(e.getMessage(), e);
            } catch (OAuthExpectationFailedException e) {
                AppLogService.error(e.getMessage(), e);
            } catch (OAuthCommunicationException e) {
                AppLogService.error(e.getMessage(), e);
            } catch (ClientProtocolException e) {
                AppLogService.error(e.getMessage(), e);
            } catch (IOException e) {
                AppLogService.error(e.getMessage(), e);
            } catch (IllegalStateException e) {
                AppLogService.error(e.getMessage(), e);
            }
        }

        return null;
    }

    /**
     * Finds a cookie by its name
     * @param request the request
     * @param strKey the cookie name
     * @return the cookie found, <code>null</code> otherwise.
     */
    private Cookie findCookie(HttpServletRequest request, String strKey) {
        if (StringUtils.isBlank(strKey)) {
            return null;
        }

        for (Cookie cookie : request.getCookies()) {
            if (strKey.equals(cookie.getName())) {
                return cookie;
            }
        }

        return null;
    }

    /**
     * Creates a cookie
     * @param strKey the cookie name
     * @param strValue the value
     */
    private void createCookie(String strKey, String strValue) {
        Cookie cookie = new Cookie(strKey, strValue);
        LocalVariables.getResponse().addCookie(cookie);
    }

    /**
     *
     *{@inheritDoc}
     */
    public void logout(LuteceUser user) {
        // nothing
    }

    // SETTERS
    /**
     * Sets the auth service name
     * @param strAuthServiceName the service name
     */
    public void setAuthServiceName(String strAuthServiceName) {
        _strAuthServiceName = strAuthServiceName;
    }

    /**
     * Set the name
     * @param strName the service key
     */
    public void setName(String strName) {
        _strName = strName;
    }

    /**
     * Sets the icon url
     * @param strIconUrl icon url
     */
    public void setIconUrl(String strIconUrl) {
        _strIconUrl = strIconUrl;
    }

    /**
     * The request token url
     * @return the request token url
     */
    public String getRequestTokenEndpointUrl() {
        return _strRequestTokenEndpointUrl;
    }

    /**
     * The request token url
     * @param strRequestTokenEndpointUrl the request token url
     */
    public void setRequestTokenEndpointUrl(String strRequestTokenEndpointUrl) {
        _strRequestTokenEndpointUrl = strRequestTokenEndpointUrl;
    }

    /**
     * The access token url
     * @return the access token url
     */
    public String getAccessTokenEndpointUrl() {
        return _strAccessTokenEndpointUrl;
    }

    /**
     * Access token url
     * @param strAccessTokenEndpointUrl the access token url
     */
    public void setAccessTokenEndpointUrl(String strAccessTokenEndpointUrl) {
        _strAccessTokenEndpointUrl = strAccessTokenEndpointUrl;
    }

    /**
     * Gets The authorize/authenticate url
     * @return The authorize/authenticate url
     */
    public String getAuthorizeWebsiteUrl() {
        return _strAuthorizeWebsiteUrl;
    }

    /**
     * The authorize/authenticate url
     * @param strAuthorizeWebsiteUrl the authorize url
     */
    public void setAuthorizeWebsiteUrl(String strAuthorizeWebsiteUrl) {
        _strAuthorizeWebsiteUrl = strAuthorizeWebsiteUrl;
    }

    /**
     * Returns the consumer key
     * @return the consumer key
     */
    public String getConsumerKey() {
        return _strConsumerKey;
    }

    /**
     * Sets the consumer key
     * @param strConsumerKey the consumer key
     */
    public void setConsumerKey(String strConsumerKey) {
        _strConsumerKey = strConsumerKey;
    }

    /**
     * Returns the consumer secret
     * @return consumer secret
     */
    public String getConsumerSecret() {
        return _strConsumerSecret;
    }

    /**
     * Consumer secret
     * @param strConsumerSecret consumer secret
     */
    public void setConsumerSecret(String strConsumerSecret) {
        _strConsumerSecret = strConsumerSecret;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return super.toString() + "{" + this.getConsumerKey() + "," + this.getConsumerSecret() + ","
                + this.getAuthorizeWebsiteUrl() + "," + this.getRequestTokenEndpointUrl() + ","
                + this.getAccessTokenEndpointUrl() + "}";
    }

    /**
     *  credential url
     *  @return  credential url
     */
    public String getCredentialUrl() {
        return _strCredentialUrl;
    }

    /**
     * Set the credential url
     * @param strCredentialUrl credential url
     */
    public void setCredentialUrl(String strCredentialUrl) {
        _strCredentialUrl = strCredentialUrl;
    }

    /**
     * Gets the credentials format
     * @return format
     */
    public String getCredentialFormat() {
        return _strCredentialFormat;
    }

    /**
     * Credentials format
     * @param strCredentialFormat strCredentialFormat
     */
    public void setCredentialFormat(String strCredentialFormat) {
        this._strCredentialFormat = strCredentialFormat;
    }
}