Omaha #3509 Aded support for custom XACML policies

Change-Id: I37c0aac34cbcc30be2a48876cef27cdf97c35a33

Former-commit-id: e9c310b4d8 [formerly 1410dc479e [formerly 1b1cd7789f835fd73dbc0d939df03f6417600154]]
Former-commit-id: 1410dc479e
Former-commit-id: b68b812dbc
This commit is contained in:
Benjamin Phillippe 2014-08-11 14:06:37 -05:00
parent 73b2585d80
commit 5b6104a8ad
5 changed files with 651 additions and 130 deletions

View file

@ -36,7 +36,8 @@ Require-Bundle: com.raytheon.uf.common.registry.schemas.ebxml;bundle-version="1.
org.eclipse.jetty;bundle-version="7.6.14",
com.raytheon.uf.edex.security;bundle-version="1.14.0",
org.opensaml;bundle-version="1.0.0",
com.raytheon.uf.common.security;bundle-version="1.14.0"
com.raytheon.uf.common.security;bundle-version="1.14.0",
org.joda.time;bundle-version="1.6.2"
Export-Package: com.raytheon.uf.edex.registry.ebxml,
com.raytheon.uf.edex.registry.ebxml.acp,
com.raytheon.uf.edex.registry.ebxml.dao,

View file

@ -2,9 +2,10 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="xacmlInterceptor" class="com.raytheon.uf.edex.registry.acp.xacml.XACMLInterceptor">
<bean id="xacmlInterceptor" class="com.raytheon.uf.edex.registry.acp.xacml.interceptor.XACMLInterceptor">
<constructor-arg ref="XACMLPolicyAdministrator"/>
<constructor-arg ref="XACMLPolicyDecisionPoint"/>
<constructor-arg ref="registryObjectDao"/>
</bean>
<bean id="XACMLPolicyDecisionPoint" class="com.raytheon.uf.edex.registry.acp.xacml.XACMLPolicyDecisionPoint"/>

View file

@ -1,128 +0,0 @@
package com.raytheon.uf.edex.registry.acp.xacml;
import java.io.ByteArrayOutputStream;
import java.security.Principal;
import oasis.names.tc.ebxml.regrep.wsdl.registry.services.v4.MsgRegistryException;
import org.apache.cxf.message.Message;
import org.apache.cxf.rt.security.xacml.AbstractXACMLAuthorizingInterceptor;
import org.opensaml.xacml.ctx.RequestType;
import org.opensaml.xacml.ctx.ResponseType;
import org.opensaml.xacml.ctx.ResultType;
import org.opensaml.xacml.policy.ObligationType;
import org.opensaml.xacml.policy.ObligationsType;
import org.opensaml.xacml.policy.PolicySetType;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.io.MarshallerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.edex.registry.acp.xacml.engine.obligation.XACMLObligationEvaluator;
import com.raytheon.uf.edex.registry.acp.xacml.exception.XACMLException;
/**
*
*
* Policy enforcement point (PEP) - The system entity that performs access
* control, by making decision requests and enforcing authorization decisions.
* This term is defined in a joint effort by the IETF Policy Framework Working
* Group and the Distributed Management Task Force (DMTF)/Common Information
* Model (CIM) in [RFC3198]. This term corresponds to "Access Enforcement
* Function" (AEF) in [ISO10181-3].
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 7/09/2014 724 bphillip Initial Coding
* </pre>
*
* @author bphillip
* @version 1
*/
public class XACMLInterceptor extends AbstractXACMLAuthorizingInterceptor {
/** The logger */
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(XACMLInterceptor.class);
private XACMLPolicyAdministrator xacmlPolicyAdmin;
private XACMLPolicyDecisionPoint pdp;
public XACMLInterceptor(XACMLPolicyAdministrator xacmlPolicyAdmin,
XACMLPolicyDecisionPoint pdp) throws MsgRegistryException {
this.xacmlPolicyAdmin = xacmlPolicyAdmin;
this.pdp = pdp;
}
@Override
public ResponseType performRequest(RequestType request, Message message)
throws Exception {
if(statusHandler.isPriorityEnabled(Priority.DEBUG)){
statusHandler.debug(outputRequest(request));
}
PolicySetType defaultPolicy = xacmlPolicyAdmin
.getPolicySet("urn:oasis:names:tc:xacml:2.0:data-delivery:default-policySet");
ResponseType response = pdp.evaluate(defaultPolicy, request);
return response;
}
/**
* Handle any Obligations returned by the PDP
*
* @throws XACMLException
*/
protected void handleObligations(RequestType request, Principal principal,
Message message, ResultType result) throws XACMLException {
ObligationsType obligationObject = result.getObligations();
if (obligationObject != null
&& !obligationObject.getObligations().isEmpty()) {
statusHandler.info("Evaluating "
+ obligationObject.getObligations().size()
+ " obligations!");
for (ObligationType obligation : result.getObligations()
.getObligations()) {
XACMLObligationEvaluator.getInstance().evaluate(obligation,
request);
}
}
}
private String outputRequest(XMLObject xmlObject) throws Exception {
try {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration
.getMarshallerFactory();
Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject);
Element element = marshaller.marshall(xmlObject);
ByteArrayOutputStream byteArrayOutputStrm = new ByteArrayOutputStream();
DOMImplementationRegistry registry = DOMImplementationRegistry
.newInstance();
DOMImplementationLS impl = (DOMImplementationLS) registry
.getDOMImplementation("LS");
LSSerializer writer = impl.createLSSerializer();
LSOutput output = impl.createLSOutput();
output.setByteStream(byteArrayOutputStrm);
writer.write(element, output);
return byteArrayOutputStrm.toString();
} catch (Exception e) {
throw new Exception("Error Serializing the SAML Response", e);
}
}
}

View file

@ -0,0 +1,289 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.registry.acp.xacml.interceptor;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.RemoveObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.UpdateObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryRequest;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryRequestType;
import oasis.names.tc.ebxml.regrep.xsd.spi.v4.CatalogObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.spi.v4.FilterObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.spi.v4.ValidateObjectsRequest;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.interceptor.security.SAMLSecurityContext;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageContentsList;
import org.apache.cxf.rt.security.xacml.RequestComponentBuilder;
import org.apache.cxf.rt.security.xacml.XACMLConstants;
import org.apache.cxf.security.SecurityContext;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.saml.ext.AssertionWrapper;
import org.joda.time.DateTime;
import org.opensaml.xacml.ctx.ActionType;
import org.opensaml.xacml.ctx.AttributeType;
import org.opensaml.xacml.ctx.AttributeValueType;
import org.opensaml.xacml.ctx.EnvironmentType;
import org.opensaml.xacml.ctx.RequestType;
import org.opensaml.xacml.ctx.ResourceType;
import org.opensaml.xacml.ctx.SubjectType;
import org.w3c.dom.Element;
/**
*
* This class generates XACML authorization requests from SOAP and REST requests.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 8/11/201r 1712 bphillip Initial Creation
* </pre>
*
* @author bphillip
* @version 1
*/
public class RegistryXACMLRequestBuilder {
/**
* Creates and empty XACMLRequestBuilder
*/
public RegistryXACMLRequestBuilder() {
}
/**
* Creates a list of requests for the given resources. A request per
* resource is created due to the fact that individual registry objects may
* have specific access control policies assigned to them.
*
* @param isSoapCall
* True if this is a SOAP request
* @param principal
* The principal on the request
* @param roles
* The role of the requesting user
* @param message
* The actual message
* @param resources
* The resources involved with the request
* @return A list of
* @throws Exception
*/
public List<RequestType> createRequestList(boolean isSoapCall,
Principal principal, List<String> roles, Message message,
List<RegistryObjectType> resources) throws Exception {
// Gets the issuer of the message if one is specified
String issuer = getIssuer(message);
// Gets the action being executed
String actionToUse = getAction(message, isSoapCall);
List<RequestType> requests = new ArrayList<RequestType>(
resources.size());
/*
* Create a request per resource
*/
for (RegistryObjectType registryObject : resources) {
requests.add(createRequest(principal, roles, issuer, actionToUse,
registryObject, isSoapCall));
}
return requests;
}
/**
* Creates an XACML request for the given resource
* @param principal The principal on the message
* @param roles The role(s) of the user making the request
* @param issuer The issuer of the message
* @param actionToUse The action being executed by the request
* @param registryObject The registry object involved with the request
* @param isSoapCall True if this is a soap call
* @return An XACML request using the given resource
*/
private RequestType createRequest(Principal principal, List<String> roles,
String issuer, String actionToUse,
RegistryObjectType registryObject, boolean isSoapCall) {
// Build the Subject
List<AttributeType> attributes = new ArrayList<AttributeType>();
AttributeValueType subjectIdAttributeValue = RequestComponentBuilder
.createAttributeValueType(principal.getName());
AttributeType subjectIdAttribute = RequestComponentBuilder
.createAttributeType(XACMLConstants.SUBJECT_ID,
XACMLConstants.XS_STRING, issuer,
Collections.singletonList(subjectIdAttributeValue));
attributes.add(subjectIdAttribute);
if (roles != null) {
List<AttributeValueType> roleAttributes = new ArrayList<AttributeValueType>(roles.size());
for (String role : roles) {
if (role != null) {
AttributeValueType subjectRoleAttributeValue = RequestComponentBuilder
.createAttributeValueType(role);
roleAttributes.add(subjectRoleAttributeValue);
}
}
if (!roleAttributes.isEmpty()) {
AttributeType subjectRoleAttribute = RequestComponentBuilder
.createAttributeType(XACMLConstants.SUBJECT_ROLE,
XACMLConstants.XS_ANY_URI, issuer,
roleAttributes);
attributes.add(subjectRoleAttribute);
}
}
SubjectType subjectType = RequestComponentBuilder.createSubjectType(
attributes, null);
attributes.clear();
// Build the Resource
attributes.add(RequestComponentBuilder.createAttributeType(
XACMLConstants.RESOURCE_ID, XACMLConstants.XS_STRING, null,
Collections.singletonList(RequestComponentBuilder
.createAttributeValueType(registryObject.getId()))));
ResourceType resourceType = RequestComponentBuilder.createResourceType(
attributes, null);
// Build the Action
AttributeValueType actionAttributeValue = RequestComponentBuilder
.createAttributeValueType(actionToUse);
AttributeType actionAttribute = RequestComponentBuilder
.createAttributeType(XACMLConstants.ACTION_ID,
XACMLConstants.XS_STRING, null,
Collections.singletonList(actionAttributeValue));
attributes.clear();
attributes.add(actionAttribute);
ActionType actionType = RequestComponentBuilder
.createActionType(attributes);
// Environment
attributes.clear();
DateTime dateTime = new DateTime();
AttributeValueType environmentAttributeValue = RequestComponentBuilder
.createAttributeValueType(dateTime.toString());
AttributeType environmentAttribute = RequestComponentBuilder
.createAttributeType(XACMLConstants.CURRENT_DATETIME,
XACMLConstants.XS_DATETIME, null,
Collections.singletonList(environmentAttributeValue));
attributes.add(environmentAttribute);
EnvironmentType environmentType = RequestComponentBuilder
.createEnvironmentType(attributes);
// Build the Request
RequestType request = RequestComponentBuilder.createRequestType(
Collections.singletonList(subjectType),
Collections.singletonList(resourceType), actionType,
environmentType);
return request;
}
/**
* Gets the registry request object from the soap message
* @param message The message to get the registry request object from
* @return The registry request message extracted from the received xml message
*/
private RegistryRequestType getRequestFromSoapMessage(Message message) {
if (message instanceof SoapMessage) {
MessageContentsList content = (MessageContentsList) ((SoapMessage) message)
.getContent(List.class);
if (!content.isEmpty()) {
Object obj = content.get(0);
if (obj instanceof RegistryRequestType) {
return (RegistryRequestType) obj;
}
}
}
return null;
}
/**
* Gets the issuer from the message
* @param message The message to get the issuer from
* @return The issuer of the message
* @throws WSSecurityException If errors occur while extracting the issuer
*/
private String getIssuer(Message message) throws WSSecurityException {
SecurityContext sc = message.get(SecurityContext.class);
if (sc instanceof SAMLSecurityContext) {
Element assertionElement = ((SAMLSecurityContext) sc)
.getAssertionElement();
if (assertionElement != null) {
AssertionWrapper wrapper = new AssertionWrapper(
assertionElement);
return wrapper.getIssuerString();
}
}
return null;
}
/**
* Gets the action from the message
* @param message The message to get the action from
* @param isSoapCall True if this is a soap call
* @return The action contained in the message
*/
private String getAction(Message message, boolean isSoapCall) {
String actionToUse = null;
RegistryRequestType request = getRequestFromSoapMessage(message);
if (isSoapCall) {
if (request instanceof CatalogObjectsRequest) {
actionToUse = "catalog";
} else if (request instanceof FilterObjectsRequest) {
actionToUse = "filter";
} else if (request instanceof QueryRequest) {
actionToUse = "read";
} else if (request instanceof RemoveObjectsRequest) {
actionToUse = "delete";
} else if (request instanceof SubmitObjectsRequest) {
actionToUse = "create";
} else if (request instanceof UpdateObjectsRequest) {
actionToUse = "update";
} else if (request instanceof ValidateObjectsRequest) {
actionToUse = "validate";
} else {
throw new IllegalArgumentException("Unsupported request type: "
+ request.getClass());
}
} else {
// For REST use the HTTP Verb
if (message.get(Message.WSDL_OPERATION) == null
&& message.get(Message.HTTP_REQUEST_METHOD) != null) {
actionToUse = (String) message.get(Message.HTTP_REQUEST_METHOD);
}
}
return actionToUse;
}
}

View file

@ -0,0 +1,358 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.registry.acp.xacml.interceptor;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.RemoveObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.SubmitObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.lcm.v4.UpdateObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryRequest;
import oasis.names.tc.ebxml.regrep.xsd.query.v4.QueryResponse;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefListType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectListType;
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryRequestType;
import oasis.names.tc.ebxml.regrep.xsd.spi.v4.CatalogObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.spi.v4.FilterObjectsRequest;
import oasis.names.tc.ebxml.regrep.xsd.spi.v4.ValidateObjectsRequest;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.security.AccessDeniedException;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageContentsList;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.security.LoginSecurityContext;
import org.apache.cxf.security.SecurityContext;
import org.apache.ws.security.saml.ext.OpenSAMLUtil;
import org.opensaml.xacml.XACMLObject;
import org.opensaml.xacml.ctx.DecisionType;
import org.opensaml.xacml.ctx.RequestType;
import org.opensaml.xacml.ctx.ResponseType;
import org.opensaml.xacml.ctx.ResultType;
import org.opensaml.xacml.policy.ObligationType;
import org.opensaml.xacml.policy.ObligationsType;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.util.CollectionUtil;
import com.raytheon.uf.edex.registry.acp.xacml.XACMLPolicyAdministrator;
import com.raytheon.uf.edex.registry.acp.xacml.XACMLPolicyDecisionPoint;
import com.raytheon.uf.edex.registry.acp.xacml.engine.obligation.XACMLObligationEvaluator;
import com.raytheon.uf.edex.registry.acp.xacml.exception.XACMLException;
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao;
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
/**
*
*
* Policy enforcement point (PEP) - The system entity that performs access
* control, by making decision requests and enforcing authorization decisions.
* This term is defined in a joint effort by the IETF Policy Framework Working
* Group and the Distributed Management Task Force (DMTF)/Common Information
* Model (CIM) in [RFC3198]. This term corresponds to "Access Enforcement
* Function" (AEF) in [ISO10181-3].
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 7/09/2014 724 bphillip Initial Coding
* 8/08/2014 1720 bphillip Implemented support for custom XACML access policies
* </pre>
*
* @author bphillip
* @version 1
*/
public class XACMLInterceptor extends AbstractPhaseInterceptor<Message> {
/** The logger */
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(XACMLInterceptor.class);
/** The slot containing the id of the custom XACML policy */
private static final String POLICY_SLOT_NAME = "urn:oasis:names:tc:ebxml-regrep:rim:RegistryObject:accessControlPolicy";
/** The id of the default XACML policy set */
private static final String DEFAULT_POLICY = "urn:oasis:names:tc:xacml:2.0:data-delivery:default-policySet";
/** XACML Policy Administrator object which manages XACML policies */
private XACMLPolicyAdministrator xacmlPolicyAdmin;
/** The XACML Policy Decision point */
private XACMLPolicyDecisionPoint pdp;
/** Registry object data access object used for registry objects */
private RegistryObjectDao registryObjectDao;
/**
* Builder object that builds XACML authorization requests from the registry
* requests
*/
private RegistryXACMLRequestBuilder requestBuilder;
/**
* Constructs a new XACMLInterceptor
*
* @param xacmlPolicyAdmin
* The policy admin
* @param pdp
* The policy decision point
* @param registryObjectDao
* The registry object data access object
*/
public XACMLInterceptor(XACMLPolicyAdministrator xacmlPolicyAdmin,
XACMLPolicyDecisionPoint pdp, RegistryObjectDao registryObjectDao) {
super(Phase.POST_INVOKE);
OpenSAMLUtil.initSamlEngine();
this.xacmlPolicyAdmin = xacmlPolicyAdmin;
this.pdp = pdp;
this.registryObjectDao = registryObjectDao;
requestBuilder = new RegistryXACMLRequestBuilder();
}
@Override
public void handleMessage(Message message) throws Fault {
SecurityContext sc = message.get(SecurityContext.class);
boolean isSoapCall = (message != null && message
.get(Message.WSDL_OPERATION) != null);
if (sc instanceof LoginSecurityContext) {
LoginSecurityContext loginSecurityContext = (LoginSecurityContext) sc;
Principal principal = sc.getUserPrincipal();
Set<Principal> principalRoles = loginSecurityContext.getUserRoles();
List<String> roles = new ArrayList<String>();
if (principalRoles != null) {
for (Principal p : principalRoles) {
if (p != principal) {
roles.add(p.getName());
}
}
}
List<RequestType> requestList = null;
List<RegistryObjectType> resources = null;
try {
resources = getResources(message, isSoapCall);
requestList = requestBuilder.createRequestList(isSoapCall,
principal, roles, message, resources);
} catch (Exception e1) {
throw new SecurityException("Error generating XACML requests!",
e1);
}
try {
boolean accessPermitted = true;
for (int i = 0; i < requestList.size() && accessPermitted; i++) {
ResponseType response = performRequest(requestList.get(i),
resources.get(i));
ResultType result = response.getResult();
// Handle any Obligations returned by the PDP
handleObligations(requestList.get(i), principal, message,
result);
if (result != null
&& (result.getDecision().getDecision() == DecisionType.DECISION.Permit)
&& (result.getResourceId() == null)) {
continue;
}
statusHandler.warn("XACML authorization not permitted:");
accessPermitted = false;
}
if (accessPermitted) {
return;
}
} catch (Exception e) {
statusHandler.error("An error occurred during XACML authorization. Defaulting to Unauthorized", e);
throw new AccessDeniedException("Unauthorized");
}
} else {
statusHandler
.error("The SecurityContext was not an instance of LoginSecurityContext. No authorization "
+ "is possible as a result");
}
throw new AccessDeniedException("Unauthorized");
}
/**
* Performs the XACML authorization request
*
* @param request
* The authorization request
* @param resource
* The resource contained in the request
* @return The XACML authorization response
* @throws EbxmlRegistryException
* If errors occur retrieving the XACML policy object
*/
private ResponseType performRequest(RequestType request,
RegistryObjectType resource) throws EbxmlRegistryException {
ResponseType response = null;
XACMLObject policy = null;
String policyName = resource.getSlotValue(POLICY_SLOT_NAME);
if (policyName == null) {
policy = xacmlPolicyAdmin.getPolicyObject(DEFAULT_POLICY);
} else {
policy = xacmlPolicyAdmin.getPolicyObject(policyName);
if (policy == null) {
statusHandler
.warn("Policy ["
+ policyName
+ "] does not exist. Using default access control policy!");
policy = xacmlPolicyAdmin.getPolicyObject(DEFAULT_POLICY);
}
}
response = pdp.evaluate(policy, request);
return response;
}
/**
* Gets the resources from the message and retrieves them from the registry
* database if possible
*
* @param message
* The message to get the resources from
* @param isSoapCall
* True if this is a SOAP call
* @return The list of registry object resources referenced by the message
* @throws EbxmlRegistryException
* If errors occur while querying for the objects from the
* registry database
*/
private List<RegistryObjectType> getResources(Message message,
boolean isSoapCall) throws EbxmlRegistryException {
List<RegistryObjectType> registryObjects = Collections.emptyList();
List<String> ids = getResourceIds(message, isSoapCall);
if (!CollectionUtil.isNullOrEmpty(ids)) {
registryObjects = registryObjectDao.getById(ids);
}
return registryObjects;
}
/**
* Extracts the ids of the resources from the message
*
* @param message
* The message to get the resource ids from
* @param isSoapCall
* True if this is a SOAP call
* @return The list of resources ids extracted from the message
* @throws EbxmlRegistryException
* If an invalid message is submitted
*/
private List<String> getResourceIds(Message message, boolean isSoapCall)
throws EbxmlRegistryException {
List<String> ids = new ArrayList<String>();
ObjectRefListType refList = null;
RegistryObjectListType objList = null;
if (isSoapCall) {
RegistryRequestType request = null;
MessageContentsList content = (MessageContentsList) ((SoapMessage) message)
.getContent(List.class);
if (!content.isEmpty()) {
Object obj = content.get(0);
if (obj instanceof RegistryRequestType) {
request = (RegistryRequestType) obj;
}
}
if (request == null) {
throw new EbxmlRegistryException(
"Could not determine request type!");
}
if (request instanceof CatalogObjectsRequest) {
refList = ((CatalogObjectsRequest) request).getObjectRefList();
objList = ((CatalogObjectsRequest) request)
.getOriginalObjects();
} else if (request instanceof FilterObjectsRequest) {
objList = ((FilterObjectsRequest) request).getOriginalObjects();
} else if (request instanceof QueryRequest) {
QueryResponse queryResponse = (QueryResponse) ((SoapMessage) message
.getExchange().getOutMessage()).getContent(List.class)
.get(0);
refList = queryResponse.getObjectRefList();
objList = queryResponse.getRegistryObjectList();
} else if (request instanceof RemoveObjectsRequest) {
refList = ((RemoveObjectsRequest) request).getObjectRefList();
} else if (request instanceof SubmitObjectsRequest) {
objList = ((SubmitObjectsRequest) request)
.getRegistryObjectList();
} else if (request instanceof UpdateObjectsRequest) {
refList = ((UpdateObjectsRequest) request).getObjectRefList();
} else if (request instanceof ValidateObjectsRequest) {
refList = ((ValidateObjectsRequest) request).getObjectRefList();
objList = ((ValidateObjectsRequest) request)
.getOriginalObjects();
} else {
throw new IllegalArgumentException("Unsupported request type: "
+ request.getClass());
}
if (refList != null) {
for (ObjectRefType ref : refList.getObjectRef()) {
ids.add(ref.getId());
}
}
if (objList != null) {
for (RegistryObjectType regObj : objList.getRegistryObject()) {
ids.add(regObj.getId());
}
}
}
return ids;
}
/**
* Handle any Obligations returned by the PDP
*
* @throws XACMLException
*/
protected void handleObligations(RequestType request, Principal principal,
Message message, ResultType result) throws XACMLException {
ObligationsType obligationObject = result.getObligations();
if (obligationObject != null
&& !obligationObject.getObligations().isEmpty()) {
statusHandler.info("Evaluating "
+ obligationObject.getObligations().size()
+ " obligations!");
for (ObligationType obligation : result.getObligations()
.getObligations()) {
XACMLObligationEvaluator.getInstance().evaluate(obligation,
request);
}
}
}
}