com.google.gsa.valve.modules.krb.KerberosAuthorizationProcess.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gsa.valve.modules.krb.KerberosAuthorizationProcess.java

Source

/**
 * Copyright (C) 2008 Google - Enterprise EMEA SE
 *
 * 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 com.google.gsa.valve.modules.krb;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;

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

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.log4j.Logger;

import org.htmlparser.Parser;
import org.htmlparser.visitors.NodeVisitor;

import com.google.gsa.AuthorizationProcessImpl;
import com.google.gsa.Credentials;
import com.google.gsa.RequestType;
import com.google.gsa.WebProcessor;
import com.google.gsa.valve.configuration.ValveConfiguration;
import com.google.gsa.valve.modules.utils.AuthorizationUtils;
import com.google.gsa.valve.modules.utils.HTTPAuthZProcessor;
import com.google.gsa.valve.modules.utils.HTTPVisitor;
import com.google.krb5.Krb5Credentials;

import java.net.MalformedURLException;
import java.net.URL;

import java.net.URLDecoder;

/**
 * This class manages the authorization process for Kerberos protected 
 * content sources. It creates an HTTP connection to any Kerberized URL 
 * that is passed to the authenticate method. If the authorization 
 * process is succesful, the response is sent back to the caller, including 
 * the content (if it's not a HEAD request). In that case a 200 (OK) error 
 * message is returned, and if there is any other error is sent back as well.
 * <p>
 * It uses the user Kerberos ticket that has to be passed to its authorize() 
 * method. The default Kerberos credential, where the ticket is recovered, 
 * is "krb5".
 * 
 * @see KerberosAuthenticationProcess
 * 
 */
public class KerberosAuthorizationProcess implements AuthorizationProcessImpl {

    private Logger logger = null;
    private WebProcessor webProcessor = null;
    private Krb5Credentials credentials = null;
    private Credentials creds = null;
    //Header
    private Header[] headers = null;
    //Max Connections
    private int maxConnectionsPerHost = -1;
    private int maxTotalConnections = -1;
    //Method
    private HttpMethodBase method = null;

    //Var that tells the default Credential ID for Kerberos
    private static final String KRB5_ID = "krb5";

    //Config
    private ValveConfiguration valveConf;

    //Encoding
    private static final String encoder = "UTF-8";

    /**
     * Class constructor - default
     */
    public KerberosAuthorizationProcess() {
        //Instantiate logger
        logger = Logger.getLogger(KerberosAuthorizationProcess.class);
    }

    /**
     * Class constructor
     * <p>
     * It sets the user credentials at the same time
     * 
     * @param credentials Kerberos credentials
     */
    public KerberosAuthorizationProcess(Krb5Credentials credentials) {

        //Instantiate logger
        logger = Logger.getLogger(KerberosAuthorizationProcess.class);

        //set credentials
        this.credentials = credentials;

    }

    /**
     * Sets user's Kerberos credentials
     * 
     * @param credentials Kerberos credentials
     */
    public void setKrbCredentials(Krb5Credentials credentials) {
        this.credentials = credentials;
    }

    /**
     * Gets Kerberos credentials
     * 
     * @return Kerberos credentials
     */
    public Krb5Credentials getKrbCredentials() {
        return (this.credentials);
    }

    /**
     * Sets user generic credentials
     * 
     * @param creds user credentials
     */
    public void setCredentials(Credentials creds) {
        this.creds = creds;
    }

    /**
     * Sets the Valve Configuration instance to read the parameters 
     * from there
     * 
     * @param valveConf the Valve configuration instance
     */
    public void setValveConfiguration(ValveConfiguration valveConf) {
        this.valveConf = valveConf;

    }

    /**
     * 
     * This is the main method that does the authorization and should be 
     * invoked by the classes that would like to check if the user is 
     * priviledged to access to the document (url) against the Kerberized 
     * protected source that serves it.
     * <p>
     * The Kerberos user ticket is read from the credentials sent in the 
     * setCredentials() method. The default Kerberos credential, where the 
     * ticket is recovered, is "krb5".
     * <p>
     * If it is a HEAD request, it means it's not necessary to get the content, 
     * and that's why this process only cares about the HTTP result code. That 
     * result code is returned back to the caller, and if the request is not a 
     * HEAD (i.e. usually GET), the content is sent as well if the overall 
     * result is OK.
     * 
     * @param request HTTP request
     * @param response HTTP response
     * @param responseCookies vector that contains the authentication cookies
     * @param url the document url
     * @param id the default credential id
     * 
     * @return the HTTP error code
     * 
     * @throws HttpException
     * @throws IOException
     */
    public int authorize(HttpServletRequest request, HttpServletResponse response, Cookie[] responseCookies,
            String url, String id) throws HttpException, IOException {

        logger.debug("Krb Authorization");

        String loginUrl = null;

        loginUrl = valveConf.getLoginUrl();

        maxConnectionsPerHost = (new Integer(valveConf.getMaxConnectionsPerHost())).intValue();
        maxTotalConnections = (new Integer(valveConf.getMaxTotalConnections())).intValue();

        logger.debug("KrbAuthZ maxConnectionsPerHost: " + maxConnectionsPerHost);
        logger.debug("KrbAuthZ maxTotalConnections: " + maxTotalConnections);

        // Protection
        if (webProcessor == null) {
            // Instantiate Web processor
            if ((maxConnectionsPerHost != -1) && (maxTotalConnections != -1)) {
                webProcessor = new WebProcessor(maxConnectionsPerHost, maxTotalConnections);
            } else {
                webProcessor = new WebProcessor();
            }
        }

        //
        // Launch the authorization process
        //

        // Initialize status code
        int statusCode = HttpServletResponse.SC_UNAUTHORIZED;

        //set credentials
        if (creds != null) {
            logger.debug("creds is not null");
            if (creds.getCredential(KRB5_ID) != null) {
                credentials = new Krb5Credentials(valveConf.getKrbConfig().getKrbconfig(),
                        valveConf.getKrbConfig().getKrbini(), creds.getCredential(KRB5_ID).getSubject());
            }
        }

        if (credentials == null) {

            // no authZ header, can't auth this URL
            logger.debug("No Kerberos credentials");
            return statusCode;

        } else {

            boolean isHead = AuthorizationUtils.isHead(request, valveConf);
            logger.debug("isHead?: " + isHead);
            setHeaders();

            // Protection
            if (webProcessor != null) {

                // Protection
                try {
                    // Process authz request
                    String requestType = RequestType.GET_REQUEST;

                    if (isHead) {
                        requestType = RequestType.HEAD_REQUEST;
                    }

                    method = webProcessor.sendRequest(credentials, requestType, headers, null, url);

                    // Protection
                    if (method != null) {
                        // Cache status code
                        statusCode = method.getStatusCode();
                        logger.debug("statusCode is.... " + statusCode);

                        if (statusCode == HttpServletResponse.SC_OK) {
                            //check if it's a Head request
                            if (!isHead) {
                                //call HTTPAuthZProcessor
                                HTTPAuthZProcessor.processResponse(response, method, url, loginUrl);
                            }
                        } else {

                            logger.debug("not AuthZ : should return response Code");
                        }
                    }

                    // Garbagge collect
                    if (method != null) {
                        method.releaseConnection();
                        method = null;
                    }

                } catch (Exception e) {
                    // Log error
                    logger.error("authorization failure: " + e.getMessage(), e);
                    statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

                    // Garbagge collect
                    logger.debug("Let's release the connection");
                    method.releaseConnection();
                    method = null;
                }

            }

            //
            // End of the authorization process
            //

            // Return status code
            return statusCode;
        }

    }

    /**
     * Sets the Kerberos authentication headers when authorizing
     * 
     */
    public void setHeaders() {

        int numHeaders = 1;

        //Set HTTP headers
        headers = new Header[numHeaders];
        // Set User-Agent
        headers[0] = new Header("User-Agent",
                "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0");

    }

}