From 9dc5a7829e9521ac29196515e1384f552068a649 Mon Sep 17 00:00:00 2001 From: Ade Lee Date: Tue, 19 Apr 2016 22:32:33 -0400 Subject: Realm: allow auth instances to support multiple realms In practice, most folks will use something like DirAclAuthz to manage their realm. Rather than requiring a new authz plugin for each realm, we allow the authz plugin to support multiple realms (as a comma separated list). For the Acl plugins in particular, we expand the authorize call to allow the caller to pass in the realm as well as the resource and operation. The resource queried would then be constructed on the fly as realm.resource Examples will be provided in the wiki page. Trac Ticket 2041 --- .../certsrv/authorization/IAuthzSubsystem.java | 3 +++ .../server/kra/rest/KeyRequestService.java | 8 +++---- .../org/dogtagpki/server/kra/rest/KeyService.java | 6 ++--- .../netscape/cms/servlet/key/KeyRequestDAO.java | 12 +++++----- .../cmscore/authorization/AuthzSubsystem.java | 27 ++++++++++++++++++---- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java b/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java index 156643897..c7d8df56b 100644 --- a/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java +++ b/base/common/src/com/netscape/certsrv/authorization/IAuthzSubsystem.java @@ -80,6 +80,9 @@ public interface IAuthzSubsystem extends ISubsystem { public AuthzToken authorize(String authzMgrName, IAuthToken authToken, String exp) throws EBaseException; + public AuthzToken authorize(String authzMgrName, IAuthToken authToken, + String resource, String operation, String realm) throws EBaseException; + /** * Authorize the user against the specified realm. Looks for authz manager * associated with the plugin and authenticates if present. diff --git a/base/kra/src/org/dogtagpki/server/kra/rest/KeyRequestService.java b/base/kra/src/org/dogtagpki/server/kra/rest/KeyRequestService.java index 41d78af53..103b78923 100644 --- a/base/kra/src/org/dogtagpki/server/kra/rest/KeyRequestService.java +++ b/base/kra/src/org/dogtagpki/server/kra/rest/KeyRequestService.java @@ -175,7 +175,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource String realm = data.getRealm(); if (realm != null) { - authz.checkRealm(realm, getAuthToken(), null, "keyRequest", "archive"); + authz.checkRealm(realm, getAuthToken(), null, "certServer.kra.requests.archival", "execute"); } response = dao.submitRequest(data, uriInfo, getRequestor()); auditArchivalRequestMade(response.getRequestInfo().getRequestId(), ILogger.SUCCESS, data.getClientKeyId()); @@ -304,7 +304,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource RequestId start, Integer pageSize, Integer maxResults, Integer maxTime, String realm) { if (realm != null) { try { - authz.checkRealm(realm, getAuthToken(), null, "keyRequests", "list"); + authz.checkRealm(realm, getAuthToken(), null, "certServer.kra.requests", "list"); } catch (EAuthzAccessDenied e) { throw new UnauthorizedException("Not authorized to list these requests", e); } catch (EAuthzUnknownRealm e) { @@ -468,7 +468,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource } String realm = data.getRealm(); if (realm != null) { - authz.checkRealm(realm, getAuthToken(), null, "keyRequest", "generateSymkey"); + authz.checkRealm(realm, getAuthToken(), null, "certServer.kra.requests.symkey", "execute"); } response = dao.submitRequest(data, uriInfo, getRequestor()); @@ -502,7 +502,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource } String realm = data.getRealm(); if (realm != null) { - authz.checkRealm(realm, getAuthToken(), null, "keyRequest", "generateAsymkey"); + authz.checkRealm(realm, getAuthToken(), null, "certServer.kra.requests.asymkey", "execute"); } response = dao.submitRequest(data, uriInfo, getRequestor()); diff --git a/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java b/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java index 255d8d614..74b58b8a2 100644 --- a/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java +++ b/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java @@ -422,7 +422,7 @@ public class KeyService extends PKIService implements KeyResource { if (realm != null) { try { - authz.checkRealm(realm, getAuthToken(), null, "keys", "list"); + authz.checkRealm(realm, getAuthToken(), null, "certServer.kra.keys", "list"); } catch (EAuthzAccessDenied e) { throw new UnauthorizedException("Not authorized to list these keys", e); } catch (EAuthzUnknownRealm e) { @@ -509,7 +509,7 @@ public class KeyService extends PKIService implements KeyResource { if (info != null) { // return the first one, but first confirm that the requester has access to this key try { - authz.checkRealm(info.getRealm(), getAuthToken(), info.getOwnerName(), "key", "read"); + authz.checkRealm(info.getRealm(), getAuthToken(), info.getOwnerName(), "certServer.kra.key", "read"); } catch (EAuthzAccessDenied e) { throw new UnauthorizedException("Not authorized to read this key", e); } catch (EBaseException e) { @@ -681,7 +681,7 @@ public class KeyService extends PKIService implements KeyResource { IKeyRecord rec = null; try { rec = repo.readKeyRecord(keyId.toBigInteger()); - authz.checkRealm(rec.getRealm(), getAuthToken(), rec.getOwnerName(), "key", "read"); + authz.checkRealm(rec.getRealm(), getAuthToken(), rec.getOwnerName(), "certServer.kra.key", "read"); KeyInfo info = createKeyDataInfo(rec, true); auditRetrieveKey(ILogger.SUCCESS, null, keyId, auditInfo); diff --git a/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java b/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java index 04bb6f2ec..00e313a80 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java +++ b/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java @@ -169,7 +169,7 @@ public class KeyRequestDAO extends CMSRequestDAO { } authz.checkRealm(request.getRealm(), authToken, request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER), - "keyRequest", "read"); + "certServer.kra.request", "read"); KeyRequestInfo info = createKeyRequestInfo(request, uriInfo); return info; @@ -264,7 +264,7 @@ public class KeyRequestDAO extends CMSRequestDAO { } try { - authz.checkRealm(rec.getRealm(), authToken, rec.getOwnerName(), "key", "recover"); + authz.checkRealm(rec.getRealm(), authToken, rec.getOwnerName(), "certServer.kra.key", "recover"); } catch (EAuthzUnknownRealm e) { throw new UnauthorizedException("Invalid realm", e); } catch (EBaseException e) { @@ -322,7 +322,7 @@ public class KeyRequestDAO extends CMSRequestDAO { } try { - authz.checkRealm(rec.getRealm(), authToken, rec.getOwnerName(), "key", "recover"); + authz.checkRealm(rec.getRealm(), authToken, rec.getOwnerName(), "certServer.kra.key", "recover"); } catch (EAuthzUnknownRealm e) { throw new UnauthorizedException("Invalid realm", e); } catch (EBaseException e) { @@ -504,7 +504,7 @@ public class KeyRequestDAO extends CMSRequestDAO { IRequest request = queue.findRequest(id); authz.checkRealm(request.getRealm(), authToken, request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER), - "keyRequest", "approve"); + "certServer.kra.requests", "execute"); service.addAgentAsyncKeyRecovery(id.toString(), requestor); } @@ -514,7 +514,7 @@ public class KeyRequestDAO extends CMSRequestDAO { String realm = request.getRealm(); authz.checkRealm(realm, authToken, request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER), - "keyRequest", "reject"); + "certServer.kra.requests", "execute"); request.setRequestStatus(RequestStatus.REJECTED); queue.updateRequest(request); } @@ -524,7 +524,7 @@ public class KeyRequestDAO extends CMSRequestDAO { String realm = request.getRealm(); authz.checkRealm(realm, authToken, request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER), - "keyRequest", "cancel"); + "certServer.kra.requests", "execute"); request.setRequestStatus(RequestStatus.CANCELED); queue.updateRequest(request); } diff --git a/base/server/cmscore/src/com/netscape/cmscore/authorization/AuthzSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/authorization/AuthzSubsystem.java index 354485897..378777f99 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/authorization/AuthzSubsystem.java +++ b/base/server/cmscore/src/com/netscape/cmscore/authorization/AuthzSubsystem.java @@ -17,8 +17,10 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cmscore.authorization; +import java.util.Arrays; import java.util.Enumeration; import java.util.Hashtable; +import java.util.List; import java.util.Vector; import org.apache.commons.codec.binary.StringUtils; @@ -227,7 +229,7 @@ public class AuthzSubsystem implements IAuthzSubsystem { */ public AuthzToken authorize( String authzMgrInstName, IAuthToken authToken, - String resource, String operation) + String resource, String operation, String realm) throws EAuthzMgrNotFound, EBaseException { AuthzManagerProxy proxy = mAuthzMgrInsts.get(authzMgrInstName); @@ -243,9 +245,20 @@ public class AuthzSubsystem implements IAuthzSubsystem { if (authzMgrInst == null) { throw new EAuthzMgrNotFound(CMS.getUserMessage("CMS_AUTHORIZATION_AUTHZMGR_NOT_FOUND", authzMgrInstName)); } + + if ((realm != null) && (resource != null)) { + resource = realm + "." + resource; + } return (authzMgrInst.authorize(authToken, resource, operation)); } + @Override + public AuthzToken authorize(String authzMgrName, IAuthToken authToken, String resource, String operation) + throws EBaseException { + return authorize(authzMgrName, authToken, resource, operation, null); + } + + @Override public AuthzToken authorize( String authzMgrInstName, IAuthToken authToken, String exp) throws EAuthzMgrNotFound, EBaseException { @@ -485,7 +498,7 @@ public class AuthzSubsystem implements IAuthzSubsystem { throw new EAuthzUnknownRealm("Realm not found"); } - AuthzToken authzToken = authorize(mgrName, authToken, resource, operation); + AuthzToken authzToken = authorize(mgrName, authToken, resource, operation, realm); if (authzToken == null) { throw new EAuthzAccessDenied("Not authorized by ACL realm"); } @@ -496,9 +509,13 @@ public class AuthzSubsystem implements IAuthzSubsystem { IAuthzManager mgr = proxy.getAuthzManager(); if (mgr != null) { IConfigStore cfg = mgr.getConfigStore(); - String mgrRealm = cfg.getString(PROP_REALM, null); - if (StringUtils.equals(mgrRealm, realm)) { - return mgr.getName(); + String mgrRealmString = cfg.getString(PROP_REALM, null); + if (mgrRealmString == null) continue; + + List mgrRealms = Arrays.asList(mgrRealmString.split(",")); + for (String mgrRealm : mgrRealms) { + if (StringUtils.equals(mgrRealm, realm)) + return mgr.getName(); } } } -- cgit