Package org.pac4j.openid.client

Source Code of org.pac4j.openid.client.BaseOpenIdClient

/*
  Copyright 2012 - 2014 Jerome Leleu

   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.
*/
package org.pac4j.openid.client;

import java.util.List;

import org.openid4java.OpenIDException;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.discovery.Identifier;
import org.openid4java.message.AuthRequest;
import org.openid4java.message.AuthSuccess;
import org.openid4java.message.MessageException;
import org.openid4java.message.ParameterList;
import org.openid4java.message.ax.FetchRequest;
import org.pac4j.core.client.BaseClient;
import org.pac4j.core.client.Mechanism;
import org.pac4j.core.client.RedirectAction;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.exception.TechnicalException;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.util.CommonHelper;
import org.pac4j.openid.credentials.OpenIdCredentials;

/**
* This class is a base implementation for an OpenID protocol client based on the openid4java library. It should work
* for all OpenID clients. In subclasses, some methods are to be implemented / customized for specific needs depending
* on the client.
*
* @author Jerome Leleu
* @since 1.4.0
*/
public abstract class BaseOpenIdClient<U extends CommonProfile> extends BaseClient<OpenIdCredentials, U> {

    private static final String OPENID_MODE = "openid.mode";

    private static final String CANCEL_MODE = "cancel";

    public final static String DISCOVERY_INFORMATION = "discoveryInformation";

    private ConsumerManager consumerManager;

    @Override
    protected void internalInit() {
        CommonHelper.assertNotBlank("callbackUrl", this.callbackUrl);
        this.consumerManager = new ConsumerManager();
    }

    /**
     * Return the user identifier for the web context.
     *
     * @param context
     * @return the user identifier
     */
    protected abstract String getUser(WebContext context);

    /**
     * Return the name of the attribute storing in session the discovery information.
     *
     * @return the name of the attribute storing in session the discovery information
     */
    protected String getDiscoveryInformationSessionAttributeName() {
        return getName() + "#" + DISCOVERY_INFORMATION;
    }

    /**
     * Get a fetch request for attributes.
     *
     * @return a fetch request for attributes
     * @throws MessageException
     */
    protected abstract FetchRequest getFetchRequest() throws MessageException;

    @Override
    @SuppressWarnings("rawtypes")
    protected RedirectAction retrieveRedirectAction(final WebContext context) {
        final String userIdentifier = getUser(context);
        CommonHelper.assertNotBlank("openIdUser", userIdentifier);

        try {
            // perform discovery on the user-supplied identifier
            final List discoveries = this.consumerManager.discover(userIdentifier);

            // attempt to associate with the OpenID provider
            // and retrieve one service endpoint for authentication
            final DiscoveryInformation discoveryInformation = this.consumerManager.associate(discoveries);

            // save discovery information in session
            context.setSessionAttribute(getDiscoveryInformationSessionAttributeName(), discoveryInformation);

            final String contextualCallbackUrl = getContextualCallbackUrl(context);
            // create authentication request to be sent to the OpenID provider
            final AuthRequest authRequest = this.consumerManager.authenticate(discoveryInformation,
                    contextualCallbackUrl);

            // create fetch request for attributes
            final FetchRequest fetchRequest = getFetchRequest();
            if (fetchRequest != null) {
                authRequest.addExtension(fetchRequest);
            }

            final String redirectionUrl = authRequest.getDestinationUrl(true);
            logger.debug("redirectionUrl : {}", redirectionUrl);
            return RedirectAction.redirect(redirectionUrl);
        } catch (final OpenIDException e) {
            logger.error("OpenID exception", e);
            throw new TechnicalException("OpenID exception", e);
        }
    }

    @Override
    protected boolean isDirectRedirection() {
        return false;
    }

    @Override
    protected OpenIdCredentials retrieveCredentials(final WebContext context) {
        final String mode = context.getRequestParameter(OPENID_MODE);
        // cancelled authentication
        if (CommonHelper.areEquals(mode, CANCEL_MODE)) {
            logger.debug("authentication cancelled");
            return null;
        }

        // parameters list returned by the provider
        final ParameterList parameterList = new ParameterList(context.getRequestParameters());

        // retrieve the previously stored discovery information
        final DiscoveryInformation discoveryInformation = (DiscoveryInformation) context
                .getSessionAttribute(getDiscoveryInformationSessionAttributeName());

        // create credentials
        final OpenIdCredentials credentials = new OpenIdCredentials(discoveryInformation, parameterList, getName());
        logger.debug("credentials : {}", credentials);
        return credentials;
    }

    /**
     * Create the appropriate OpenID profile.
     *
     * @param authSuccess
     * @return the appropriate OpenID profile
     * @throws MessageException
     */
    protected abstract U createProfile(AuthSuccess authSuccess) throws MessageException;

    @Override
    protected U retrieveUserProfile(final OpenIdCredentials credentials, final WebContext context) {
        final ParameterList parameterList = credentials.getParameterList();
        final DiscoveryInformation discoveryInformation = credentials.getDiscoveryInformation();
        logger.debug("parameterList : {}", parameterList);
        logger.debug("discoveryInformation : {}", discoveryInformation);

        try {
            final String contextualCallbackUrl = getContextualCallbackUrl(context);
            // verify the response
            final VerificationResult verification = this.consumerManager.verify(contextualCallbackUrl, parameterList,
                    discoveryInformation);

            // examine the verification result and extract the verified identifier
            final Identifier verified = verification.getVerifiedId();
            if (verified != null) {
                final AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
                logger.debug("authSuccess : {}", authSuccess);

                final U profile = createProfile(authSuccess);
                profile.setId(verified.getIdentifier());
                logger.debug("profile : {}", profile);
                return profile;
            }
        } catch (final OpenIDException e) {
            logger.error("OpenID exception", e);
            throw new TechnicalException("OpenID exception", e);
        }

        final String message = "No verifiedId found";
        logger.error(message);
        throw new TechnicalException(message);
    }

    @Override
    public Mechanism getMechanism() {
        return Mechanism.OPENID_PROTOCOL;
    }
}
TOP

Related Classes of org.pac4j.openid.client.BaseOpenIdClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.