summaryrefslogtreecommitdiffstats
path: root/base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2012-10-10 04:38:05 -0500
committerEndi Sukma Dewata <edewata@redhat.com>2012-11-08 11:20:05 -0500
commitcb209df95c4dee11f2a912e20b417fa3bc41c88f (patch)
treeb50824cdfd3bc4ec3db905b94ef7750d9ff74844 /base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java
parent906acfd2c82d195a7c55a2af7c4d7abe8ed2655a (diff)
downloadpki-cb209df95c4dee11f2a912e20b417fa3bc41c88f.tar.gz
pki-cb209df95c4dee11f2a912e20b417fa3bc41c88f.tar.xz
pki-cb209df95c4dee11f2a912e20b417fa3bc41c88f.zip
Added ACLInterceptor.
Previously ACL checking was done in PKIRealm by matching the URL. This code has been replaced by ACLInterceptor which will intercept RESTEasy method invocations. This allows more precise mapping of REST methods to ACL entries in acl.ldif. Ticket #287
Diffstat (limited to 'base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java')
-rw-r--r--base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java154
1 files changed, 154 insertions, 0 deletions
diff --git a/base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java b/base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java
new file mode 100644
index 000000000..bcb0b80a2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java
@@ -0,0 +1,154 @@
+//--- 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 com.netscape.certsrv.acls;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.Principal;
+import java.util.Properties;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.ext.Provider;
+
+import org.jboss.resteasy.annotations.interception.Precedence;
+import org.jboss.resteasy.annotations.interception.ServerInterceptor;
+import org.jboss.resteasy.core.ResourceMethod;
+import org.jboss.resteasy.core.ServerResponse;
+import org.jboss.resteasy.spi.Failure;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.jboss.resteasy.spi.interception.PreProcessInterceptor;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cmscore.realm.PKIPrincipal;
+
+
+/**
+ * @author Endi S. Dewata
+ */
+@Provider
+@ServerInterceptor
+@Precedence("SECURITY")
+public class ACLInterceptor implements PreProcessInterceptor {
+
+ Properties authProperties;
+
+ @Context
+ ServletContext servletContext;
+
+ @Context
+ SecurityContext securityContext;
+
+ public synchronized void loadAuthProperties() throws IOException {
+
+ if (authProperties != null) return;
+
+ URL url = servletContext.getResource("/WEB-INF/auth.properties");
+ authProperties = new Properties();
+ authProperties.load(url.openStream());
+ }
+
+ @Override
+ public ServerResponse preProcess(
+ HttpRequest request,
+ ResourceMethod resourceMethod
+ ) throws Failure, WebApplicationException {
+
+ // Get ACL mapping for the method.
+ Method method = resourceMethod.getMethod();
+ ACLMapping aclMapping = method.getAnnotation(ACLMapping.class);
+
+ // If not available, get ACL mapping for the class.
+ if (aclMapping == null) {
+ Class<?> clazz = method.getDeclaringClass();
+ aclMapping = clazz.getAnnotation(ACLMapping.class);
+ }
+
+ // If still not available, it's unprotected, allow request.
+ if (aclMapping == null) return null;
+
+ Principal principal = securityContext.getUserPrincipal();
+
+ // If unauthenticated, reject request.
+ if (principal == null) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ // If unrecognized principal, reject request.
+ if (!(principal instanceof PKIPrincipal)) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ PKIPrincipal pkiPrincipal = (PKIPrincipal)principal;
+ IAuthToken authToken = pkiPrincipal.getAuthToken();
+
+ // If missing auth token, reject request.
+ if (authToken == null) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ try {
+ loadAuthProperties();
+
+ String name = aclMapping.value();
+ String value = authProperties.getProperty(name);
+
+ // If no property defined, allow request.
+ if (value == null) return null;
+
+ String values[] = value.split(",");
+
+ // If invalid mapping, reject request.
+ if (values.length != 2) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ // Check authorization.
+ IAuthzSubsystem mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+ AuthzToken authzToken = mAuthz.authorize(
+ "DirAclAuthz",
+ authToken,
+ values[0], // resource
+ values[1]); // operation
+
+ // If not authorized, reject request.
+ if (authzToken == null) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ } catch (EAuthzAccessDenied e) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+
+ } catch (IOException|EBaseException e) {
+ e.printStackTrace();
+ throw new Failure(e);
+ }
+
+ // Allow request.
+ return null;
+ }
+}