diff -ru /usr/local/src/jboss-3.0.6-src/jetty/src/main/org/jboss/jetty/security/JBossUserRealm.java jetty/src/main/org/jboss/jetty/security/JBossUserRealm.java
--- /usr/local/src/jboss-3.0.6-src/jetty/src/main/org/jboss/jetty/security/JBossUserRealm.java	Fri Dec 13 00:39:03 2002
+++ jetty/src/main/org/jboss/jetty/security/JBossUserRealm.java	Thu Feb 20 12:27:46 2003
@@ -25,10 +25,12 @@
 import org.mortbay.http.HttpRequest;
 import org.mortbay.http.UserPrincipal;
 import org.mortbay.http.UserRealm;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
 
 /** An implementation of UserRealm that integrates with the JBossSX
  * security manager associted with the web application.
- * @author  Scott_Stark@displayscape.com
+ * @author  Scott_Stark@displayscape.com, Cert Auth by pdawes@users.sf.net
  * @version $Revision: 1.7.2.6 $
  */
 
@@ -47,7 +49,7 @@
   class JBossUserPrincipal
     implements UserPrincipal	// Jetty API
   {
-    private final SimplePrincipal _principal;	// JBoss API
+    final SimplePrincipal _principal;	// JBoss API
     private String                _password;
 
     JBossUserPrincipal(String name)
@@ -69,7 +71,7 @@
       char[] passwordChars = password.toCharArray();
       if (_log.isDebugEnabled())
 	_log.debug("authenticating: Name:"+_principal+" Password:****"/*+password*/);
-      if(_authMgr!=null &&_authMgr.isValid(this, passwordChars))
+      if(_authMgr!=null &&_authMgr.isValid(this._principal, passwordChars))
       {
 	if (_log.isDebugEnabled())
 	  _log.debug("authenticated: "+_principal);
@@ -119,7 +121,8 @@
     public String
       getName()
     {
-      return _principal.getName();
+      //return _principal.getName();
+      return _realmMapping.getPrincipal(_principal).getName();
     }
 
     //----------------------------------------
@@ -163,7 +166,7 @@
       boolean isUserInRole = false;
 
       Set requiredRoles = Collections.singleton(new SimplePrincipal(role));
-      if(_realmMapping!=null && _realmMapping.doesUserHaveRole(this, requiredRoles))
+      if(_realmMapping!=null && _realmMapping.doesUserHaveRole(this._principal, requiredRoles))
       {
 	if (_log.isDebugEnabled())
 	  _log.debug("JBossUserPrincipal: "+_principal+" is in Role: "+role);
@@ -186,6 +189,55 @@
     }
   }
 
+
+  // Represents a user which has been authenticated elsewhere 
+  //  (e.g. at the fronting server), and thus doesnt have credentials
+  class JBossCertificatePrincipal extends JBossUserPrincipal
+  {
+    private X509Certificate[] _certs;
+    JBossCertificatePrincipal(String name, X509Certificate[] certs)
+    {
+      super(name);
+      
+      _certs = certs;
+
+      if (_log.isDebugEnabled())
+        _log.debug("created JBossUserRealm::JBossCertificatePrincipal: "+name);
+    }
+
+
+    
+    public boolean isAuthenticated() {
+      _log.debug("JBossUserRealm::isAuthenticated called");
+      return true;
+    }
+
+    public boolean authenticate(){
+      boolean authenticated = false;
+      if (_log.isDebugEnabled())
+        _log.debug("authenticating: Name:"+_principal);
+
+      // Authenticate using the cert as the credential
+      if(_authMgr!=null &&_authMgr.isValid(_principal,_certs))
+         {
+          if (_log.isDebugEnabled())
+            _log.debug("authenticated: "+_principal);
+
+          SecurityAssociation.setPrincipal(_principal);
+          SecurityAssociation.setCredential(_certs);
+          authenticated=true;
+        }
+      else
+        {
+          _log.warn("authentication failure: "+_principal);
+        }
+
+      return authenticated;
+    }
+
+  }
+
+
   public
     JBossUserRealm(String realmName, String subjAttrName)
   {
@@ -210,7 +262,7 @@
       iniCtx=null;
 
       if (_authMgr instanceof SubjectSecurityManager)
-	_subjSecMgr = (SubjectSecurityManager) _authMgr;
+  _subjSecMgr = (SubjectSecurityManager) _authMgr;
     }
     catch (NamingException e)
     {
@@ -234,29 +286,79 @@
     return user;
   }
 
-  public UserPrincipal
+  public UserPrincipal 
     authenticate(String userName, Object credential, HttpRequest request)
   {
     if (_log.isDebugEnabled())
       _log.debug("JBossUserPrincipal: "+userName);
 
     // until we get DigestAuthentication sorted JBoss side...
-    String password=null;
-    if (credential instanceof java.lang.String)
-      password=(String)credential;
-    else
-    {
-      if (credential!=null)
-	_log.warn("digest authentication NYI - credential MUST be a String");
-      return null;
+    JBossUserPrincipal user = null;
+
+    if (credential instanceof java.lang.String) // password
+    {  
+      user = ensureUser(userName);
+      if (!user.authenticate((String)credential,request)){
+        user = null;
+      }
     }
+    
+    else if(credential instanceof java.security.cert.X509Certificate[]) // certificate
+    {   
+      java.security.cert.X509Certificate[] certs = (java.security.cert.X509Certificate[])credential;
+      user = this.authenticateFromCertificates(certs);
+    } 
+    
+    if(user != null){
+      request.setAuthType(javax.servlet.http.HttpServletRequest.CLIENT_CERT_AUTH);
+                request.setAuthUser(user.getName());
+                request.setUserPrincipal(user);
+    }
+    return user;
+  }
+
 
-    JBossUserPrincipal user = ensureUser(userName);
-    if (user.authenticate(password,request))
+  public JBossUserPrincipal authenticateFromCertificates(X509Certificate[] certs)
+  {
+
+    JBossCertificatePrincipal user = (JBossCertificatePrincipal)_users.get(certs[0]);
+    if (user == null){
+      user = new JBossCertificatePrincipal(getFilterFromCertificate(certs[0]),certs);
+      _users.put(certs[0], user);
+    }
+    if (user.authenticate()){
+      _log.debug("authenticateFromCertificates - authenticated");
       return user;
+    }
+
+    _log.debug("authenticateFromCertificates - returning NULL");
     return null;
   }
 
+  /**
+   * Takes an X509Certificate object and extracts the certificate's
+   * serial number and issuer in order to construct a unique string
+   * representing that certificate.
+   *
+   * @param cert the user's certificate.
+   * @return an LDAP filter for retrieving the user's entry.
+   */
+  private String getFilterFromCertificate(X509Certificate cert) 
+  {
+    //StringBuffer    buff = new StringBuffer("certSerialAndIssuer=");
+    StringBuffer    buff = new StringBuffer();
+    String          serialNumber =
+      cert.getSerialNumber().toString(16).toUpperCase();
+    if (serialNumber.length() % 2 != 0) {
+      buff.append("0");
+    }
+    buff.append(serialNumber);
+    buff.append(" ");
+    buff.append(cert.getIssuerDN().toString());
+    String  filter = buff.toString();
+    return filter;
+  }
+
   public void disassociate(UserPrincipal user)
   {
     SecurityAssociation.setPrincipal(null);
diff -ru /usr/local/src/jboss-3.0.6-src/jetty/src/main/org/mortbay/http/ajp/AJP13Connection.java jetty/src/main/org/mortbay/http/ajp/AJP13Connection.java
--- /usr/local/src/jboss-3.0.6-src/jetty/src/main/org/mortbay/http/ajp/AJP13Connection.java	Sat Dec 28 16:08:43 2002
+++ jetty/src/main/org/mortbay/http/ajp/AJP13Connection.java	Thu Feb 20 11:20:12 2003
@@ -21,7 +21,9 @@
 import org.mortbay.http.Version;
 import org.mortbay.util.Code;
 import org.mortbay.util.LineInput;
-
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.io.StringBufferInputStream;
 
 /* ------------------------------------------------------------ */
 /** 
@@ -198,13 +200,18 @@
                             request.setAttribute(value,packet.getString());
                             break;
                         case 9: // SSL session
-                            Code.warning("not implemented: sslsession="+value);
+                            //Code.warning("not implemented: sslsession="+value);
                             break;
                         case 8: // SSL cipher
                             request.setAttribute("javax.servlet.request.cipher_suite",value);
                             break;
                         case 7: // SSL cert
-                            request.setAttribute("javax.servlet.request.X509Certificate",value);
+                            //request.setAttribute("javax.servlet.request.X509Certificate",value);
+							CertificateFactory cf = CertificateFactory.getInstance("X.509");
+							InputStream certstream = new StringBufferInputStream(value);
+							X509Certificate cert = (X509Certificate) cf.generateCertificate(certstream);
+							X509Certificate certs[] = {cert};
+							request.setAttribute("javax.servlet.request.X509Certificate",certs);
                             break;
                         case 6: // JVM Route
                             request.setAttribute("org.mortbay.http.ajp.JVMRoute",value);
