package examples.security.cert;


import weblogic.security.Certificate;
import weblogic.security.Entity;
import weblogic.security.X500Name;
import weblogic.security.acl.CertAuthenticator;
import weblogic.security.acl.BasicRealm;
import weblogic.security.acl.Realm;
import weblogic.security.acl.User;


/**
 * A very simple certificate authentication example.  This
 * example maps the name in the email address of a
 * certificate's holder directly to a WebLogic user.
 *
 * <p>
 * Other, more realistic, approaches to authentication
 * include the following:
 *
 * <ul>
 * <li>Search an LDAP directory for a user with a matching
 * certificate, and return that user, if any.
 *
 * <li>Maintain an RDBMS table that maps certificate public keys to
 * WebLogic user names, and perform an RDBMS lookup to obtain a user
 * name.
 * </ul>
 *
 * @author Copyright (c) 1999-2000 by BEA Systems, Inc. All Rights Reserved.  
 */
public class SimpleCertAuthenticator
  implements CertAuthenticator
{
  private BasicRealm realm;

  public SimpleCertAuthenticator()
  {
    realm = Realm.getRealm("weblogic");
  }

  
  /**
   * Attempt to authenticate a remote user.
   *
   * @param userName ignored by this example
   * @param certs used to attempt to map from email addrss to WebLogic
   * user
   * @param ssl if true, this example always returns null
   * @return authenticated user, or null if authentication failed
   */
  public User authenticate(String userName, Certificate[] certs, boolean ssl)
  {
    // This implementation only trusts certificates that originate
    // from a successful two-way SSL handshake.
    
    if (ssl == false)
    {
      return null;
    }
    
    User result = null;
    
    Certificate cert = certs[0];
    
    Entity holder = cert.getHolder();

    // System.out.println("*** Holder of this cert is " + holder);
    
    // If the holder isn't an X.500 name, we don't know how to extract
    // the email address.
    
    if (holder instanceof X500Name)
    {
      X500Name x500holder = (X500Name) holder;
      
      String email = x500holder.getEmail();

      if (email != null)
      {
	int at = email.indexOf("@");

	if (at > 0)
	{
	  String name = email.substring(0, at);

	  // Make sure that the user we've pulled out of the email
	  // address really exists.
	  
	  result = realm.getUser(name);
	}
      }
    }
    
    return result;
  }
}
