Package org.jboss.web.tomcat.security.login

Source Code of org.jboss.web.tomcat.security.login.WebAuthentication

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.web.tomcat.security.login;

import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.UUID;

import javax.naming.NamingException;
import javax.servlet.http.Cookie;

import org.apache.catalina.Container;
import org.apache.catalina.Pipeline;
import org.apache.catalina.Session;
import org.apache.catalina.Valve;
import org.apache.catalina.authenticator.Constants;
import org.apache.catalina.authenticator.SingleSignOn;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve;

//$Id: WebAuthentication.java 94411 2009-10-06 11:37:05Z anil.saldhana@jboss.com $

/**
*  JBAS-4077: Programmatic Web Login
@author Anil.Saldhana@redhat.com
@since  Mar 12, 2007
@version $Revision: 94411 $
*/
public class WebAuthentication
{
   private static final String AUTH_TYPE = "PROGRAMMATIC_WEB_LOGIN";

   public WebAuthentication()
   {
   }

   /**
    * Login an user via the CLIENT-CERT method
    * @param certs X509 certificates
    * @return Authenticated User Principal
    */
   public boolean login(X509Certificate[] certs)
   {
      //Get the active request
      Request request = ActiveRequestResponseCacheValve.activeRequest.get();
      if (request == null)
         throw new IllegalStateException("request is null");
      Principal p = request.getContext().getRealm().authenticate(certs);
      if (p != null)
      {
         register(request, p, null, null);
      }
      return p != null;
   }

   /**
    * Login an user via the BASIC, FORM, DIGEST methods
    * @param username
    * @param credential
    * @return
    * @throws NamingException
    */
   public boolean login(String username, Object credential)
   {
      //Get the active request
      Request request = ActiveRequestResponseCacheValve.activeRequest.get();
      if (request == null)
         throw new IllegalStateException("request is null");

      Principal p = null;
      if (credential instanceof String)
      {
         p = request.getContext().getRealm().authenticate(username, (String) credential);
      }
      else if (credential instanceof byte[])
      {
         p = request.getContext().getRealm().authenticate(username, (byte[]) credential);
      }
      if (p != null)
      {
         register(request, p, username, credential);
      }
      return p != null;
   }

   /**
    * Log the user out
    *
    */
   public void logout()
   {
      //Get the active request
      Request request = ActiveRequestResponseCacheValve.activeRequest.get();
      if (request == null)
         throw new IllegalStateException("request is null");
      unregister(request);
   }

   /**
    * Register the principal with the request, session etc just the way AuthenticatorBase does
    * @param request Catalina Request
    * @param principal User Principal generated via authentication
    * @param username username passed by the user (null for client-cert)
    * @param credential Password (null for client-cert and digest)
    */
   protected void register(Request request, Principal principal, String username, Object password)
   {
      request.setAuthType(AUTH_TYPE);
      request.setUserPrincipal(principal);

      //Cache the authentication principal in the session
      Session session = request.getSessionInternal(false);
      if (session != null)
      {
         session.setAuthType(AUTH_TYPE);
         session.setPrincipal(principal);
         if (username != null)
            session.setNote(Constants.SESS_USERNAME_NOTE, username);
         else
            session.removeNote(Constants.SESS_USERNAME_NOTE);
         if (password != null)
            session.setNote(Constants.SESS_PASSWORD_NOTE, getPasswordAsString(password));
         else
            session.removeNote(Constants.SESS_PASSWORD_NOTE);
      }

      // JBAS-4424: Programmatic web authentication with SSO
      SingleSignOn sso = this.getSingleSignOn(request);
      if (sso == null)
         return;

      // Only create a new SSO entry if the SSO did not already set a note
      // for an existing entry (as it would do with subsequent requests
      // for DIGEST and SSL authenticated contexts)
      String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE);
      if (ssoId == null)
      {
         // Construct a cookie to be returned to the client
         ssoId = generateSessionId();
         Cookie cookie = new Cookie(Constants.SINGLE_SIGN_ON_COOKIE, ssoId);
         cookie.setMaxAge(-1);
         cookie.setPath("/");

         // Bugzilla 41217
         cookie.setSecure(request.isSecure());

         // Bugzilla 34724
         String ssoDomain = sso.getCookieDomain();
         if (ssoDomain != null)
         {
            cookie.setDomain(ssoDomain);
         }

         Response response = ActiveRequestResponseCacheValve.activeResponse.get();
         response.addCookie(cookie);

         // Register this principal with our SSO valve
         sso.register(ssoId, principal, AUTH_TYPE, username, this.getPasswordAsString(password));
         request.setNote(Constants.REQ_SSOID_NOTE, ssoId);

      }
      else
      {
         // Update the SSO session with the latest authentication data
         sso.update(ssoId, principal, AUTH_TYPE, username, this.getPasswordAsString(password));
      }

      // Always associate a session with a new SSO reqistration.
      // SSO entries are only removed from the SSO registry map when
      // associated sessions are destroyed; if a new SSO entry is created
      // above for this request and the user never revisits the context, the
      // SSO entry will never be cleared if we don't associate the session
      if (session == null)
         session = request.getSessionInternal(true);
      sso.associate(ssoId, session);
   }

   /**
    * Log the user out
    * @param request
    */
   protected void unregister(Request request)
   {
      request.setAuthType(null);
      request.setUserPrincipal(null);

      // Cache the authentication principal in the session.
      Session session = request.getSessionInternal(false);
      if (session != null)
      {
         session.setAuthType(null);
         session.setPrincipal(null);
         session.removeNote(Constants.SESS_USERNAME_NOTE);
         session.removeNote(Constants.SESS_PASSWORD_NOTE);
      }
      // Unregister the SSOID.
      SingleSignOn sso = this.getSingleSignOn(request);
      if (sso != null)
      {
         String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE);
         sso.deregister(ssoId);
      }
   }

   private String getPasswordAsString(Object cred)
   {
      String p = null;

      if (cred instanceof String)
      {
         p = (String) cred;
      }
      else if (cred instanceof byte[])
      {
         p = new String((byte[]) cred);
      }
      return p;
   }

   /**
    * <p>
    * Generate and return a new session identifier for the cookie that identifies an SSO principal.
    * </p>
    *
    * @return a <code>String</code> representing the generated identifier.
    */
   private String generateSessionId()
   {
      UUID uid = UUID.randomUUID();
      String higherBits = Long.toHexString(uid.getMostSignificantBits());
      String lowerBits = Long.toHexString(uid.getLeastSignificantBits());

      return (higherBits + lowerBits).toUpperCase();
   }

   /**
    * <p>
    * Obtain a reference to the <code>SingleSignOn</code> valve, if one was configured.
    * </p>
    *
    * @param request    the <code>Request</code> object used to look up the SSO valve.
    * @return   a reference to the <code>SingleSignOn</code> valve, or <code>null</code> if no SSO valve
    * has been configured.
    */
   private SingleSignOn getSingleSignOn(Request request)
   {
      SingleSignOn sso = null;
      Container parent = request.getContext().getParent();
      while ((sso == null) && (parent != null))
      {
         if (!(parent instanceof Pipeline))
         {
            parent = parent.getParent();
            continue;
         }
         Valve valves[] = ((Pipeline) parent).getValves();
         for (int i = 0; i < valves.length; i++)
         {
            if (valves[i] instanceof SingleSignOn)
            {
               sso = (SingleSignOn) valves[i];
               break;
            }
         }
         if (sso == null)
            parent = parent.getParent();
      }
      return sso;
   }
}
TOP

Related Classes of org.jboss.web.tomcat.security.login.WebAuthentication

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.