summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2015-04-21 16:29:45 -0400
committerEndi S. Dewata <edewata@redhat.com>2015-05-05 15:16:12 -0400
commitcb32779617947a16a0bfdc519a5ecbd0ae7019aa (patch)
treec494909409b00b53a43acacc0bcef9b931bc5474
parent31d96e0ba756fd05bad0c9a577bf27ef9041d490 (diff)
downloadpki-cb32779617947a16a0bfdc519a5ecbd0ae7019aa.tar.gz
pki-cb32779617947a16a0bfdc519a5ecbd0ae7019aa.tar.xz
pki-cb32779617947a16a0bfdc519a5ecbd0ae7019aa.zip
Fixed authentication data in audit log.
The REST methods may be executed by different threads even though they are invoked in the same session. A new interceptor has been added to all subsystems to make sure the SessionContext is created properly for each thread. This will fix the authentication data in the audit log. The SessionContext has also been improved to use ThreadLocal instead of a global Hashtable. https://fedorahosted.org/pki/ticket/1054
-rw-r--r--base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java4
-rw-r--r--base/common/src/com/netscape/certsrv/base/SessionContext.java42
-rw-r--r--base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java4
-rw-r--r--base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java4
-rw-r--r--base/server/cms/src/org/dogtagpki/server/rest/SessionContextInterceptor.java100
-rw-r--r--base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java4
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/rest/TPSApplication.java4
7 files changed, 124 insertions, 38 deletions
diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java b/base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java
index d73b794da..8c6c8cbe5 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/CAApplication.java
@@ -10,10 +10,11 @@ import org.dogtagpki.server.rest.AccountService;
import org.dogtagpki.server.rest.AuditService;
import org.dogtagpki.server.rest.AuthMethodInterceptor;
import org.dogtagpki.server.rest.GroupService;
-import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.MessageFormatInterceptor;
+import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.SecurityDomainService;
import org.dogtagpki.server.rest.SelfTestService;
+import org.dogtagpki.server.rest.SessionContextInterceptor;
import org.dogtagpki.server.rest.SystemCertService;
import org.dogtagpki.server.rest.UserService;
@@ -89,6 +90,7 @@ public class CAApplication extends Application {
classes.add(PKIExceptionMapper.class);
// interceptors
+ singletons.add(new SessionContextInterceptor());
singletons.add(new AuthMethodInterceptor());
singletons.add(new ACLInterceptor());
singletons.add(new MessageFormatInterceptor());
diff --git a/base/common/src/com/netscape/certsrv/base/SessionContext.java b/base/common/src/com/netscape/certsrv/base/SessionContext.java
index 79b75508f..81debaee8 100644
--- a/base/common/src/com/netscape/certsrv/base/SessionContext.java
+++ b/base/common/src/com/netscape/certsrv/base/SessionContext.java
@@ -82,26 +82,12 @@ public class SessionContext extends Hashtable<Object, Object> {
*/
public static final String IPADDRESS = "ipAddress";
- private static Hashtable<Thread, SessionContext> mContexts = new Hashtable<Thread, SessionContext>();
+ private static ThreadLocal<SessionContext> instance = new ThreadLocal<SessionContext>();
/**
* Constructs a session context.
*/
public SessionContext() {
- super();
- }
-
- /**
- * Creates a new context and associates it with
- * the current thread. If the current thread is
- * also associated with a old context, the old
- * context will be replaced.
- */
- private static SessionContext createContext() {
- SessionContext sc = new SessionContext();
-
- setContext(sc);
- return sc;
}
/**
@@ -114,7 +100,7 @@ public class SessionContext extends Hashtable<Object, Object> {
* @param sc session context
*/
public static void setContext(SessionContext sc) {
- mContexts.put(Thread.currentThread(), sc);
+ instance.set(sc);
}
/**
@@ -125,12 +111,12 @@ public class SessionContext extends Hashtable<Object, Object> {
* @return sesssion context
*/
public static SessionContext getContext() {
- SessionContext sc = mContexts.get(Thread.currentThread());
-
- if (sc == null) {
- sc = createContext();
+ SessionContext context = instance.get();
+ if (context == null) {
+ context = new SessionContext();
+ instance.set(context);
}
- return sc;
+ return context;
}
/**
@@ -141,23 +127,13 @@ public class SessionContext extends Hashtable<Object, Object> {
* @return sesssion context
*/
public static SessionContext getExistingContext() {
- SessionContext sc = mContexts.get(Thread.currentThread());
-
- if (sc == null) {
- return null;
- }
-
- return sc;
+ return instance.get();
}
/**
* Releases the current session context.
*/
public static void releaseContext() {
- SessionContext sc = mContexts.get(Thread.currentThread());
-
- if (sc != null) {
- mContexts.remove(Thread.currentThread());
- }
+ instance.set(null);
}
}
diff --git a/base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java b/base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java
index 815763cdd..6244270c0 100644
--- a/base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java
+++ b/base/kra/src/org/dogtagpki/server/kra/rest/KRAApplication.java
@@ -10,10 +10,11 @@ import org.dogtagpki.server.rest.AccountService;
import org.dogtagpki.server.rest.AuditService;
import org.dogtagpki.server.rest.AuthMethodInterceptor;
import org.dogtagpki.server.rest.GroupService;
-import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.MessageFormatInterceptor;
+import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.SecurityDomainService;
import org.dogtagpki.server.rest.SelfTestService;
+import org.dogtagpki.server.rest.SessionContextInterceptor;
import org.dogtagpki.server.rest.SystemCertService;
import org.dogtagpki.server.rest.UserService;
@@ -67,6 +68,7 @@ public class KRAApplication extends Application {
classes.add(PKIExceptionMapper.class);
// interceptors
+ singletons.add(new SessionContextInterceptor());
singletons.add(new AuthMethodInterceptor());
singletons.add(new ACLInterceptor());
singletons.add(new MessageFormatInterceptor());
diff --git a/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java b/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java
index 1950edf29..8d6e4a983 100644
--- a/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java
+++ b/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPApplication.java
@@ -10,10 +10,11 @@ import org.dogtagpki.server.rest.AccountService;
import org.dogtagpki.server.rest.AuditService;
import org.dogtagpki.server.rest.AuthMethodInterceptor;
import org.dogtagpki.server.rest.GroupService;
-import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.MessageFormatInterceptor;
+import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.SecurityDomainService;
import org.dogtagpki.server.rest.SelfTestService;
+import org.dogtagpki.server.rest.SessionContextInterceptor;
import org.dogtagpki.server.rest.SystemCertService;
import org.dogtagpki.server.rest.UserService;
@@ -63,6 +64,7 @@ public class OCSPApplication extends Application {
classes.add(PKIExceptionMapper.class);
// interceptors
+ singletons.add(new SessionContextInterceptor());
singletons.add(new AuthMethodInterceptor());
singletons.add(new ACLInterceptor());
singletons.add(new MessageFormatInterceptor());
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SessionContextInterceptor.java b/base/server/cms/src/org/dogtagpki/server/rest/SessionContextInterceptor.java
new file mode 100644
index 000000000..bae25b660
--- /dev/null
+++ b/base/server/cms/src/org/dogtagpki/server/rest/SessionContextInterceptor.java
@@ -0,0 +1,100 @@
+//--- BEGIN COPYRIGHT BLOCK ---
+//This program is free software; you can redistribute it and/or modify
+//it under the terms of the GNU General Public License as published by
+//the Free Software Foundation; version 2 of the License.
+//
+//This program 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 General Public License for more details.
+//
+//You should have received a copy of the GNU General Public License along
+//with this program; if not, write to the Free Software Foundation, Inc.,
+//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+//(C) 2012 Red Hat, Inc.
+//All rights reserved.
+//--- END COPYRIGHT BLOCK ---
+package org.dogtagpki.server.rest;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.ext.Provider;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.ForbiddenException;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.cms.realm.PKIPrincipal;
+import com.netscape.cms.servlet.base.UserInfo;
+
+/**
+ * @author Endi S. Dewata
+ */
+@Provider
+public class SessionContextInterceptor implements ContainerRequestFilter {
+
+ @Context
+ HttpServletRequest servletRequest;
+
+ @Context
+ SecurityContext securityContext;
+
+ public Locale getLocale(HttpServletRequest req) {
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null)
+ return Locale.getDefault();
+
+ return new Locale(UserInfo.getUserLanguage(lang), UserInfo.getUserCountry(lang));
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+
+ Principal principal = securityContext.getUserPrincipal();
+
+ // If unauthenticated, ignore.
+ if (principal == null) {
+ CMS.debug("SessionContextInterceptor: Not authenticated.");
+ SessionContext.releaseContext();
+ return;
+ }
+
+ CMS.debug("SessionContextInterceptor: principal: " + principal.getName());
+
+ // If unrecognized principal, reject request.
+ if (!(principal instanceof PKIPrincipal)) {
+ CMS.debug("SessionContextInterceptor: Invalid user principal.");
+ throw new ForbiddenException("Invalid user principal.");
+ }
+
+ PKIPrincipal pkiPrincipal = (PKIPrincipal) principal;
+ IAuthToken authToken = pkiPrincipal.getAuthToken();
+
+ // If missing auth token, reject request.
+ if (authToken == null) {
+ CMS.debug("SessionContextInterceptor: No authorization token present.");
+ throw new ForbiddenException("No authorization token present.");
+ }
+
+ SessionContext context = SessionContext.getContext();
+
+ String ip = servletRequest.getRemoteAddr();
+ context.put(SessionContext.IPADDRESS, ip);
+
+ Locale locale = getLocale(servletRequest);
+ context.put(SessionContext.LOCALE, locale);
+
+ context.put(SessionContext.AUTH_TOKEN, authToken);
+ context.put(SessionContext.USER_ID, pkiPrincipal.getName());
+ context.put(SessionContext.USER, pkiPrincipal.getUser());
+ }
+}
diff --git a/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java b/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java
index c0fdc6734..ca19e38d8 100644
--- a/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java
+++ b/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java
@@ -10,9 +10,10 @@ import org.dogtagpki.server.rest.AccountService;
import org.dogtagpki.server.rest.AuditService;
import org.dogtagpki.server.rest.AuthMethodInterceptor;
import org.dogtagpki.server.rest.GroupService;
-import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.MessageFormatInterceptor;
+import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.SelfTestService;
+import org.dogtagpki.server.rest.SessionContextInterceptor;
import org.dogtagpki.server.rest.SystemCertService;
import org.dogtagpki.server.rest.UserService;
@@ -49,6 +50,7 @@ public class TKSApplication extends Application {
classes.add(PKIExceptionMapper.class);
// interceptors
+ singletons.add(new SessionContextInterceptor());
singletons.add(new AuthMethodInterceptor());
singletons.add(new ACLInterceptor());
singletons.add(new MessageFormatInterceptor());
diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/TPSApplication.java b/base/tps/src/org/dogtagpki/server/tps/rest/TPSApplication.java
index 70c8afd02..b63af8344 100644
--- a/base/tps/src/org/dogtagpki/server/tps/rest/TPSApplication.java
+++ b/base/tps/src/org/dogtagpki/server/tps/rest/TPSApplication.java
@@ -27,9 +27,10 @@ import org.dogtagpki.server.rest.AccountService;
import org.dogtagpki.server.rest.AuditService;
import org.dogtagpki.server.rest.AuthMethodInterceptor;
import org.dogtagpki.server.rest.GroupService;
-import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.MessageFormatInterceptor;
+import org.dogtagpki.server.rest.PKIExceptionMapper;
import org.dogtagpki.server.rest.SelfTestService;
+import org.dogtagpki.server.rest.SessionContextInterceptor;
import org.dogtagpki.server.rest.SystemCertService;
import org.dogtagpki.server.rest.UserService;
import org.dogtagpki.server.tps.config.ConfigService;
@@ -89,6 +90,7 @@ public class TPSApplication extends Application {
classes.add(PKIExceptionMapper.class);
// interceptors
+ singletons.add(new SessionContextInterceptor());
singletons.add(new AuthMethodInterceptor());
singletons.add(new ACLInterceptor());
singletons.add(new MessageFormatInterceptor());