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

org.picketlink.social.openid.OpenIDConsumerAuthenticator Maven / Gradle / Ivy

The newest version!
/*
 * JBoss, Home of Professional Open Source
 *
 * Copyright 2013 Red Hat, Inc. and/or its affiliates.
 *
 * 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.picketlink.social.openid;

import org.apache.catalina.Session;
import org.apache.catalina.authenticator.Constants;
import org.apache.catalina.authenticator.FormAuthenticator;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.log4j.Logger;
import org.picketlink.common.util.StringUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.Method;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;

/**
 * Tomcat Authenticator that provides OpenID based authentication
 *
 * @author Anil Saldhana
 * @since Sep 17, 2011
 */
public class OpenIDConsumerAuthenticator extends FormAuthenticator {

    protected static Logger log = Logger.getLogger(OpenIDConsumerAuthenticator.class);
    protected boolean trace = log.isTraceEnabled();

    private enum STATES {
        AUTH,
        AUTHZ,
        FINISH
    }

    ;

    public static ThreadLocal cachedPrincipal = new ThreadLocal();

    public static ThreadLocal> cachedRoles = new ThreadLocal>();
    public static String EMPTY_PASSWORD = "EMPTY";

    private String returnURL = null;

    private String requiredAttributes = "name,email,ax_firstName,ax_lastName,ax_fullName,ax_email";

    private String optionalAttributes = null;

    protected List roles = new ArrayList();

    // Whether the authenticator has to to save and restore request
    protected boolean saveRestoreRequest = true;

    protected OpenIDProcessor processor = null;

    // Incompatibilities in register() method across JBossWeb versions
    private Method theSuperRegisterMethod = null;

    public void setReturnURL(String returnURL) {
        this.returnURL = StringUtil.getSystemPropertyAsString(returnURL);
    }

    public void setRequiredAttributes(String requiredAttributes) {
        this.requiredAttributes = requiredAttributes;
    }

    public void setOptionalAttributes(String optionalAttributes) {
        this.optionalAttributes = optionalAttributes;
    }

    public void setSaveRestoreRequest(boolean saveRestoreRequest) {
        this.saveRestoreRequest = saveRestoreRequest;
    }

    /**
     * A comma separated string that represents the roles the web app needs to pass authorization
     *
     * @param roleStr
     */
    public void setRoleString(String roleStr) {
        if (roleStr == null) {
            throw new RuntimeException("Role String is null in configuration");
        }
        List tokens = StringUtil.tokenize(roleStr);
        for (String token : tokens) {
            roles.add(token);
        }
    }

    public boolean authenticate(HttpServletRequest request, HttpServletResponse response, LoginConfig loginConfig)
        throws IOException {
        if (request instanceof Request == false) {
            throw new IOException("Not of type Catalina request");
        }
        if (response instanceof Response == false) {
            throw new IOException("Not of type Catalina response");
        }
        return authenticate((Request) request, (Response) response, loginConfig);
    }

    /**
     * Authenticate the request
     *
     * @param request
     * @param response
     * @param config
     *
     * @return
     *
     * @throws java.io.IOException
     * @throws {@link              RuntimeException} when the response is not of type catalina response object
     */
    public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
        if (response instanceof Response) {
            Response catalinaResponse = (Response) response;
            return authenticate(request, catalinaResponse, config);
        }
        throw new RuntimeException("Wrong type of response:" + response);
    }

    public boolean authenticate(Request request, Response response, LoginConfig loginConfig) throws IOException {
        if (processor == null) {
            processor = new OpenIDProcessor(returnURL, requiredAttributes, optionalAttributes);
        }

        Principal userPrincipal = request.getUserPrincipal();
        if (userPrincipal != null) {
            if (trace) {
                log.trace("Logged in as:" + userPrincipal);
            }
            return true;
        }

        if (!processor.isInitialized()) {
            try {
                processor.initialize(roles);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        HttpSession httpSession = request.getSession();
        String state = (String) httpSession.getAttribute("STATE");
        if (trace) {
            log.trace("state=" + state);
        }

        if (STATES.FINISH.name().equals(state)) {
            return true;
        }

        if (state == null || state.isEmpty()) {
            return processor.prepareAndSendAuthRequest(request, response);
        }
        // We have sent an auth request
        if (state.equals(STATES.AUTH.name())) {
            Session session = request.getSessionInternal(true);
            if (saveRestoreRequest) {
                this.saveRequest(request, session);
            }

            Principal principal = processor.processIncomingAuthResult(request, response, context.getRealm());
            if (principal == null) {
                throw new RuntimeException("Principal was null. Maybe login modules need to be configured properly.");
            }
            String principalName = principal.getName();
            request.getSessionInternal().setNote(Constants.SESS_USERNAME_NOTE, principalName);
            request.getSessionInternal().setNote(Constants.SESS_PASSWORD_NOTE, "");
            request.setUserPrincipal(principal);

            if (saveRestoreRequest) {
                this.restoreRequest(request, request.getSessionInternal());
            }

            if (trace) {
                log.trace("Logged in as:" + principal);
            }

            registerWithAuthenticatorBase(request, response, principal, principalName);

            request.getSession().setAttribute("STATE", STATES.FINISH.name());
            return true;
        }
        return false;
    }

    protected void registerWithAuthenticatorBase(Request request, Response response, Principal principal, String userName) {
        try {
            register(request, response, principal, Constants.FORM_METHOD, userName, "");
        } catch (NoSuchMethodError nse) {
            if (theSuperRegisterMethod == null) {
                Class[] args = new Class[]{Request.class, HttpServletResponse.class, Principal.class, String.class,
                    String.class, String.class};
                Class superClass = getClass().getSuperclass();
                theSuperRegisterMethod = SecurityActions.getMethod(superClass, "register", args);
            }
            if (theSuperRegisterMethod != null) {
                Object[] objectArgs = new Object[]{request, response.getResponse(), principal, Constants.FORM_METHOD,
                    userName, OpenIDProcessor.EMPTY_PASSWORD};
                try {
                    theSuperRegisterMethod.invoke(this, objectArgs);
                } catch (Exception e) {
                    log.error("Unable to register:", e);
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy