Package org.jasig.portal.services

Source Code of org.jasig.portal.services.Authentication

/* Copyright 2001 The JA-SIG Collaborative.  All rights reserved.
*  See license distributed with this file and
*  available online at http://www.uportal.org/license.html
*/

package  org.jasig.portal.services;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.AuthorizationException;
import org.jasig.portal.UserIdentityStoreFactory;
import org.jasig.portal.properties.PropertiesManager;
import org.jasig.portal.security.IAdditionalDescriptor;
import org.jasig.portal.security.IOpaqueCredentials;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.security.IPrincipal;
import org.jasig.portal.security.ISecurityContext;
import org.jasig.portal.security.PortalSecurityException;
import org.jasig.portal.security.provider.ChainingSecurityContext;
import org.jasig.portal.services.persondir.IPersonAttributeDao;

/**
* Attempts to authenticate a user and retrieve attributes
* associated with the user.
* @author Ken Weiner, kweiner@unicon.net
* @author Don Fracapane (df7@columbia.edu)
* Added properties in the security properties file that hold the tokens used to
* represent the principal and credential for each security context. This version
* differs in the way the principal and credentials are set (all contexts are set
* up front after evaluating the tokens). See setContextParameters() also.
* @version $Revision: 1.55.2.1 $
* Changes put in to allow credentials and principals to be defined and held by each
* context.
*/
public class Authentication {
   
    private static final Log log = LogFactory.getLog(Authentication.class);
   
   private final static String BASE_CONTEXT_NAME = "root";
  
   protected org.jasig.portal.security.IPerson m_Person = null;
   protected ISecurityContext ic = null;

   /**
    * Attempts to authenticate a given IPerson based on a set of principals and credentials
    * @param principals
    * @param credentials
    * @param person
    * @exception PortalSecurityException
    */
   public void authenticate (HashMap principals, HashMap credentials, IPerson person) throws PortalSecurityException {
      
      // Retrieve the security context for the user
      ISecurityContext securityContext = person.getSecurityContext();
     
      //Set the principals and credentials for the security context chain
      this.configureSecurityContextChain(principals, credentials, person, securityContext, BASE_CONTEXT_NAME);
     
      // NOTE: The LoginServlet looks in the security.properties file to
      // determine what tokens to look for that represent the principals and
      // credentials for each context. It then retrieves the values from the request
      // and stores the values in the principals and credentials HashMaps that are
      // passed to the Authentication service.

      // Attempt to authenticate the user
      securityContext.authenticate();
      // Check to see if the user was authenticated
      if (securityContext.isAuthenticated()) {
         // Add the authenticated username to the person object
         // the login name may have been provided or reset by the security provider
         // so this needs to be done after authentication.
         person.setAttribute(IPerson.USERNAME, securityContext.getPrincipal().getUID());
         // Retrieve the additional descriptor from the security context
         IAdditionalDescriptor addInfo = person.getSecurityContext().getAdditionalDescriptor();
         // Process the additional descriptor if one was created
         if (addInfo != null) {
            // Replace the passed in IPerson with the additional descriptor if the
            // additional descriptor is an IPerson object created by the security context
            // NOTE: This is not the preferred method, creation of IPerson objects should be
            //       handled by the PersonManager.
            if (addInfo instanceof IPerson) {
               IPerson newPerson = (IPerson)addInfo;
               person.setFullName(newPerson.getFullName());
               for (Enumeration e = newPerson.getAttributeNames(); e.hasMoreElements();) {
                  String attributeName = (String)e.nextElement();
                  person.setAttribute(attributeName, newPerson.getAttribute(attributeName));
               }
            }
            // If the additional descriptor is a map then we can
            // simply copy all of these additional attributes into the IPerson
            else if (addInfo instanceof Map) {
               // Cast the additional descriptor as a Map
               Map additionalAttributes = (Map)addInfo;
               // Copy each additional attribute into the person object
               for (Iterator keys = additionalAttributes.keySet().iterator(); keys.hasNext();) {
                  // Get a key
                  String key = (String)keys.next();
                  // Set the attribute
                  person.setAttribute(key, additionalAttributes.get(key));
               }
            }
            else if (addInfo instanceof ChainingSecurityContext.ChainingAdditionalDescriptor) {
                // do nothing
            }
            else {
                if (log.isWarnEnabled())
                    log.warn("Authentication Service recieved " +
                            "unknown additional descriptor [" + addInfo + "]");
            }
         }
         // Populate the person object using the PersonDirectory if applicable
         if (PropertiesManager.getPropertyAsBoolean("org.jasig.portal.services.Authentication.usePersonDirectory")) {
            // Retrieve all of the attributes associated with the person logging in
            IPersonAttributeDao pa = PersonDirectory.getPersonAttributeDao();
            Map attribs = pa.getUserAttributes((String)person.getAttribute(IPerson.USERNAME));
           
            if (attribs != null) {
              // attribs may be null.  IPersonAttributeDao returns null when it does not recognize a user at all, as
              // distinguished from returning an empty Map of attributes when it recognizes a user has having no
              // attributes.
             
                // Add each of the attributes to the IPerson
                Iterator en = attribs.keySet().iterator();
                while (en.hasNext()) {
                   String key = (String)en.next();
                   // String value = (String)attribs.get(key);
                   // person.setAttribute(key, value);
                   person.setAttribute(key, attribs.get(key));
                }
            }

         }
         // Make sure the the user's fullname is set
         if (person.getFullName() == null) {
            // Use portal display name if one exists
            if (person.getAttribute("portalDisplayName") != null) {
               person.setFullName((String)person.getAttribute("portalDisplayName"));
            }
            // If not try the eduPerson displyName
            else if (person.getAttribute("displayName") != null) {
               person.setFullName((String)person.getAttribute("displayName"));
            }
            // If still no FullName use an unrecognized string
            if (person.getFullName() == null) {
               person.setFullName("Unrecognized person: " + person.getAttribute(IPerson.USERNAME));
            }
         }
         // Find the uPortal userid for this user or flunk authentication if not found
         // The template username should actually be derived from directory information.
         // The reference implemenatation sets the uPortalTemplateUserName to the default in
         // the portal.properties file.
         // A more likely template would be staff or faculty or undergraduate.
         boolean autocreate = PropertiesManager.getPropertyAsBoolean("org.jasig.portal.services.Authentication.autoCreateUsers");
         // If we are going to be auto creating accounts then we must find the default template to use
         if (autocreate && person.getAttribute("uPortalTemplateUserName") == null) {
            String defaultTemplateUserName = PropertiesManager.getProperty("org.jasig.portal.services.Authentication.defaultTemplateUserName");
            person.setAttribute("uPortalTemplateUserName", defaultTemplateUserName);
         }
         try {
            // Attempt to retrieve the UID
            int newUID = UserIdentityStoreFactory.getUserIdentityStoreImpl().getPortalUID(person,
                  autocreate);
            person.setID(newUID);
         } catch (AuthorizationException ae) {
            log.error("Exception retrieving ID", ae);
            throw  new PortalSecurityException("Authentication Service: Exception retrieving UID");
         }
        
         //TODO add IPerson cache
        
         // Record the successful authentication
         StatsRecorder.recordLogin(person);
      }
   }

   /**
    * Returns an IPerson object that can be used to hold site-specific attributes
    * about the logged on user.  This information is established during
    * authentication.
    * @return An object that implements the
    * <code>org.jasig.portal.security.IPerson</code> interface.
    */
   public IPerson getPerson () {
      return  m_Person;
   }

   /**
    * Returns an ISecurityContext object that can be used
    * later. This object is passed as part of the IChannel Interface.
    * The security context may be used to gain authorized access to
    * services.
    * @return An object that implements the
    * <code>org.jasig.portal.security.ISecurityContext</code> interface.
    */
   public ISecurityContext getSecurityContext () {
      return  ic;
   }

   /**
    * Get the principal and credential for a specific context and store them in
    * the context.
    * @param principals
    * @param credentials
    * @param ctxName
    * @param securityContext
    * @param person
    */
   public void setContextParameters (HashMap principals, HashMap credentials, String ctxName,
         ISecurityContext securityContext, IPerson person) {
      String username = (String)principals.get(ctxName);
      String credential = (String)credentials.get(ctxName);
      // If username or credential are null, this indicates that the token was not
      // set in security properties. We will then use the value for root.
      username = (username != null ? username : (String)principals.get(BASE_CONTEXT_NAME));
      credential = (credential != null ? credential : (String)credentials.get(BASE_CONTEXT_NAME));
      if (log.isDebugEnabled())
          log.debug("Authentication::setContextParameters() username: " + username);
      // Retrieve and populate an instance of the principal object
      IPrincipal principalInstance = securityContext.getPrincipalInstance();
      if (username != null && !username.equals("")) {
         principalInstance.setUID(username);
      }
      // Retrieve and populate an instance of the credentials object
      IOpaqueCredentials credentialsInstance = securityContext.getOpaqueCredentialsInstance();
      credentialsInstance.setCredentials(credential);
   }
  
   /**
    * Recureses through the {@link ISecurityContext} chain, setting the credentials
    * for each.
    * TODO This functionality should be moved into the {@link org.jasig.portal.security.provider.ChainingSecurityContext}.
    *
    * @param principals
    * @param credentials
    * @param person
    * @param securityContext
    * @param baseContextName
    * @throws PortalSecurityException
    */
   private void configureSecurityContextChain(final HashMap principals, final HashMap credentials, final IPerson person, final ISecurityContext securityContext, final String baseContextName) throws PortalSecurityException {
       this.setContextParameters (principals, credentials, baseContextName, securityContext, person);
      
       // load principals and credentials for the subContexts
       for (final Enumeration subCtxNames = securityContext.getSubContextNames(); subCtxNames.hasMoreElements(); ) {
           final String fullSubCtxName = (String)subCtxNames.nextElement();
          
           //Strip off the base of the name
           String localSubCtxName = fullSubCtxName;
           if (fullSubCtxName.startsWith(baseContextName + ".")) {
               localSubCtxName = localSubCtxName.substring(baseContextName.length() + 1);
           }
         
           final ISecurityContext sc = securityContext.getSubContext(localSubCtxName);
          
           this.configureSecurityContextChain(principals, credentials, person, sc, fullSubCtxName);
       }
   }  
}
TOP

Related Classes of org.jasig.portal.services.Authentication

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.