From 1201c80e7acab4ad6ca0ea6d716435eeabb88f4c Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Tue, 9 Oct 2012 05:04:52 -0500
Subject: [PATCH] Added PKIPrincipal.

Previously in PKIRealm the authentication token was stored in a thread
local variable. This does not work for multiple operations executed
using the same session because each operation may be handled by
different threads. A new PKIPrincipal has been added to store the
authentication token so that the threads can get the correct token
for the session.

Ticket #357
---
 .../com/netscape/cmscore/realm/PKIPrincipal.java   | 29 +++++++++++
 .../src/com/netscape/cmscore/realm/PKIRealm.java   | 57 ++++++++++++----------
 2 files changed, 60 insertions(+), 26 deletions(-)
 create mode 100644 base/common/src/com/netscape/cmscore/realm/PKIPrincipal.java

diff --git a/base/common/src/com/netscape/cmscore/realm/PKIPrincipal.java b/base/common/src/com/netscape/cmscore/realm/PKIPrincipal.java
new file mode 100644
index 0000000000000000000000000000000000000000..6f806e3e9f79bf96e81317ec57832b9347cab0f5
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/realm/PKIPrincipal.java
@@ -0,0 +1,29 @@
+package com.netscape.cmscore.realm;
+
+import java.util.List;
+
+import org.apache.catalina.realm.GenericPrincipal;
+
+import com.netscape.certsrv.authentication.IAuthToken;
+
+/**
+ * @author Endi S. Dewata
+ */
+
+public class PKIPrincipal extends GenericPrincipal {
+
+    IAuthToken authToken;
+
+    public PKIPrincipal(String name, String password, List<String> roles, IAuthToken authToken) {
+        super(name, password, roles);
+        this.authToken = authToken;
+    }
+
+    public PKIPrincipal(String name, String password, List<String> roles) {
+        this(name, password, roles, null);
+    }
+
+    public IAuthToken getAuthToken() {
+        return authToken;
+    }
+}
diff --git a/base/common/src/com/netscape/cmscore/realm/PKIRealm.java b/base/common/src/com/netscape/cmscore/realm/PKIRealm.java
index 53b31131c15125873abd48f547c1385af1afe8f8..9b4b97c2a5e0dfbb78775f5b46ec41c7a4e839c2 100644
--- a/base/common/src/com/netscape/cmscore/realm/PKIRealm.java
+++ b/base/common/src/com/netscape/cmscore/realm/PKIRealm.java
@@ -18,7 +18,6 @@ import org.apache.catalina.LifecycleException;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
 import org.apache.catalina.deploy.SecurityConstraint;
-import org.apache.catalina.realm.GenericPrincipal;
 import org.apache.catalina.realm.RealmBase;
 
 import com.netscape.certsrv.apps.CMS;
@@ -48,7 +47,6 @@ public class PKIRealm extends RealmBase {
     public final static String PROP_AUTH_FILE_PATH = "/WEB-INF/auth.properties";
     public final static int EXPRESSION_SIZE = 2;
 
-    ThreadLocal<IAuthToken> authToken = new ThreadLocal<IAuthToken>();
     Properties authzProperties;
 
     public PKIRealm() {
@@ -84,10 +82,9 @@ public class PKIRealm extends RealmBase {
             creds.set(PasswdUserDBAuthentication.CRED_UID, username);
             creds.set(PasswdUserDBAuthentication.CRED_PWD, password);
 
-            IAuthToken token = authMgr.authenticate(creds); // throws exception if authentication fails
-            authToken.set(token);
+            IAuthToken authToken = authMgr.authenticate(creds); // throws exception if authentication fails
 
-            return getPrincipal(username);
+            return getPrincipal(username, authToken);
 
         } catch (Throwable e) {
             e.printStackTrace();
@@ -116,13 +113,12 @@ public class PKIRealm extends RealmBase {
             AuthCredentials creds = new AuthCredentials();
             creds.set(CertUserDBAuthentication.CRED_CERT, certImpls);
 
-            IAuthToken token = authMgr.authenticate(creds); // throws exception if authentication fails
-            authToken.set(token);
+            IAuthToken authToken = authMgr.authenticate(creds); // throws exception if authentication fails
 
-            String username = token.getInString(CertUserDBAuthentication.TOKEN_USERID);
+            String username = authToken.getInString(CertUserDBAuthentication.TOKEN_USERID);
             logDebug("User ID: "+username);
 
-            return getPrincipal(username);
+            return getPrincipal(username, authToken);
 
         } catch (Throwable e) {
             e.printStackTrace();
@@ -133,9 +129,14 @@ public class PKIRealm extends RealmBase {
 
     @Override
     protected Principal getPrincipal(String username) {
+        return getPrincipal(username, (IAuthToken)null);
+    }
+
+    protected Principal getPrincipal(String username, IAuthToken authToken) {
+
         try {
             IUser user = getUser(username);
-            return getPrincipal(user);
+            return getPrincipal(user, authToken);
 
         } catch (Throwable e) {
             e.printStackTrace();
@@ -143,9 +144,9 @@ public class PKIRealm extends RealmBase {
         }
     }
 
-    protected Principal getPrincipal(IUser user) throws EUsrGrpException {
+    protected Principal getPrincipal(IUser user, IAuthToken authToken) throws EUsrGrpException {
         List<String> roles = getRoles(user);
-        return new GenericPrincipal(user.getUserID(), null, roles);
+        return new PKIPrincipal(user.getUserID(), null, roles, authToken);
     }
 
     protected IUser getUser(String username) throws EUsrGrpException {
@@ -249,23 +250,27 @@ public class PKIRealm extends RealmBase {
                 }
             }
 
-            IAuthzSubsystem mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
-            IAuthToken token = authToken.get();
+            Principal principal = request.getUserPrincipal();
+            if (principal instanceof PKIPrincipal) {
+                PKIPrincipal pkiPrincipal = (PKIPrincipal)principal;
+                IAuthToken authToken = pkiPrincipal.getAuthToken();
 
-            logDebug("Auth token:");
-            Enumeration<String> names = token.getElements();
-            while (names.hasMoreElements()) {
-                String name = names.nextElement();
-                Object value = token.get(name);
-                logDebug("  " + name +": " + value);
+                logDebug("Auth token:");
+                Enumeration<String> names = authToken.getElements();
+                while (names.hasMoreElements()) {
+                    String name = names.nextElement();
+                    Object value = authToken.get(name);
+                    logDebug("  " + name +": " + value);
+                }
+
+                logDebug("Resource: " + resource);
+                logDebug("Operation: " + operation);
+
+                IAuthzSubsystem mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+                AuthzToken authzToken = mAuthz.authorize("DirAclAuthz", authToken, resource, operation);
+                if (authzToken != null) return true;
             }
 
-            logDebug("Resource: " + resource);
-            logDebug("Operation: " + operation);
-
-            AuthzToken authzToken = mAuthz.authorize("DirAclAuthz", token, resource, operation);
-            if (authzToken != null) return true;
-
         } catch (Throwable e) {
             e.printStackTrace();
         }
-- 
1.7.11.4

