View Javadoc
1 /* 2 * $Header: /cvsroot/ebxmlrr/ebxmlrr/src/share/com/sun/ebxml/registry/security/authorization/RegistryPolicyFinderModule.java,v 1.3 2003/09/11 21:12:41 farrukh_najmi Exp $ 3 * 4 * ==================================================================== 5 * 6 * This code is subject to the freebxml License, Version 1.1 7 * 8 * Copyright (c) 2003 freebxml.org. All rights reserved. 9 * 10 * ==================================================================== 11 */ 12 13 package com.sun.ebxml.registry.security.authorization; 14 15 import com.sun.ebxml.registry.RegistryException; 16 import com.sun.xacml.AbstractPolicy; 17 import com.sun.xacml.MatchResult; 18 import com.sun.xacml.PolicyTreeElement; 19 20 21 import com.sun.xacml.finder.PolicyFinderResult; 22 import java.util.ArrayList; 23 import java.util.List; 24 import java.util.Collection; 25 import java.util.Iterator; 26 27 import java.net.URI; 28 29 /*** 30 * This module represents a collection of files containing polices, 31 * each of which will be searched through when trying to find a 32 * policy that is applicable to a specific request. 33 * 34 * @author Farrukh Najmi 35 */ 36 public class RegistryPolicyFinderModule extends com.sun.xacml.finder.PolicyFinderModule 37 { 38 private org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(this.getClass()); 39 com.sun.xacml.finder.PolicyFinder finder = null; 40 41 //The default Access Control Policy for the registry 42 AbstractPolicy defaultPolicy; 43 com.sun.ebxml.registry.repository.RepositoryManager rm = com.sun.ebxml.registry.repository.RepositoryManagerFactory.getInstance().getRepositoryManager(); 44 com.sun.ebxml.registry.persistence.PersistenceManagerImpl pm = com.sun.ebxml.registry.persistence.PersistenceManagerImpl.getInstance(); 45 com.sun.ebxml.registry.util.BindingUtility bu = com.sun.ebxml.registry.util.BindingUtility.getInstance(); 46 47 public static final String ASSOCIATION_TYPE_ACCESS_CONTROL_POLICY_FOR = "urn:uuid:375c8977-d54e-4e81-bebf-d87e509c9c78"; 48 49 public RegistryPolicyFinderModule() { 50 defaultPolicy = loadDefaultPolicy(); 51 } 52 53 //Load the efault Access Control Policy for the registry 54 private AbstractPolicy loadDefaultPolicy() { 55 AbstractPolicy policy = null; 56 try { 57 String idForDefaultACP = com.sun.ebxml.registry.util.RegistryProperties.getInstance().getProperty("ebxmlrr.security.authorization.defaultACP"); 58 59 policy = loadPolicy(idForDefaultACP); 60 } 61 catch (RegistryException e) { 62 log.fatal("Could not load default Access Control Policy for Registry", e); 63 } 64 65 return policy; 66 } 67 68 //Load the Access Control Policy that has the specified id 69 private AbstractPolicy loadPolicy(String id) throws RegistryException { 70 log.debug("Loading policy for id=" + id); 71 72 AbstractPolicy policy = null; 73 com.sun.ebxml.registry.repository.RepositoryItem ri = null; 74 75 if (id == null) { 76 return policy; 77 } 78 79 //First check if it is in the repository as a top level Policy 80 try { 81 ri = rm.getRepositoryItem(id); 82 } 83 catch (RegistryException e) { 84 log.debug(e); 85 } 86 87 //Not found as top level repository item 88 //See if it is a composed policy within a top level policy in repository 89 if (ri == null) { 90 //No policy found. Next find an ACP with specified URI as 91 //a value for a Slot named "ComposedPolicies". 92 AbstractPolicy rootPolicy = loadRootPolicyFor(id); 93 94 try { 95 if (rootPolicy != null) { 96 com.sun.xacml.PolicyTreeElement policyElement = getDescendantPolicyTreeElement(rootPolicy, new java.net.URI(id)); 97 if (policyElement instanceof AbstractPolicy) { 98 policy = (AbstractPolicy)policyElement; 99 } 100 } 101 } 102 catch (java.net.URISyntaxException e) { 103 throw new RegistryException(e); 104 } 105 } 106 else { 107 javax.activation.DataHandler dh = ri.getDataHandler(); 108 policy = loadPolicy(dh, finder); 109 } 110 111 return policy; 112 } 113 114 /*** 115 * Gets teh Collection of all POlicyElements that are Descendants of specified PolicyTreeElement 116 */ 117 public Collection getDescendantPolicyTreeElements(PolicyTreeElement parent) { 118 List children = parent.getChildren(); 119 ArrayList descendants = new ArrayList(parent.getChildren()); 120 Iterator iter = children.iterator(); 121 122 while (iter.hasNext()) { 123 PolicyTreeElement child = (PolicyTreeElement) iter.next(); 124 125 descendants.addAll(getDescendantPolicyTreeElements(child)); 126 } 127 return descendants; 128 } 129 130 /*** 131 * Get the descendent AbstractPolciy composed within specified PolicyTreeElement object that 132 * matches the specified id. 133 */ 134 public PolicyTreeElement getDescendantPolicyTreeElement(PolicyTreeElement parent, URI descendantId) { 135 PolicyTreeElement descendent = null; 136 137 //System.err.println("AbstractPolicy.getDescendantPolicyTreeElement: descendantId=" + descendantId); 138 139 Collection descendants = getDescendantPolicyTreeElements(parent); 140 141 Iterator iter = descendants.iterator(); 142 while (iter.hasNext()) { 143 PolicyTreeElement policyElement = (PolicyTreeElement)iter.next(); 144 //System.err.println("AbstractPolicy.getDescendantPolicyTreeElement: currentId=" + policyElement.getId()); 145 if (policyElement.getId().toString().equals(descendantId.toString())) { 146 descendent = policyElement; 147 break; 148 } 149 } 150 151 return descendent; 152 } 153 154 155 156 /*** 157 * Returns the root or top level policy that contains a descendant policy with specified 158 * id. 159 */ 160 private AbstractPolicy loadRootPolicyFor(String composedPolicyId) throws RegistryException { 161 log.debug("Loading root policy for composed policy with id=" + composedPolicyId); 162 163 AbstractPolicy rootPolicy = null; 164 165 String id = null; 166 167 org.oasis.ebxml.registry.bindings.query.ResponseOption responseOption = new org.oasis.ebxml.registry.bindings.query.ResponseOption(); 168 responseOption.setReturnType(org.oasis.ebxml.registry.bindings.query.types.ReturnTypeType.LEAFCLASS); 169 responseOption.setReturnComposedObjects(true); 170 171 String query = "SELECT eo.* from " + 172 pm.mapTableName("ExtrinsicObject") + " eo, " + 173 pm.mapTableName("Slot") + " s WHERE " + 174 "((eo.objectType = 'urn:uuid:832d1ba8-2c56-4f29-a49d-d10b0bd8f920') OR " + 175 "(eo.objectType = 'urn:uuid:7c50351e-0022-4a65-950c-ac8cda6f3e0b')) AND s.name_ = 'ComposedPolicies' AND eo.id = " + 176 "s.parent AND s.value = '" + composedPolicyId + "'"; 177 178 ArrayList objectRefs = new ArrayList(); 179 ArrayList al = pm.executeSQLQuery( query, responseOption, "ExtrinsicObject", objectRefs); 180 ArrayList ids = bu.getIdsFromRegistryObjects(al); 181 182 int cnt = ids.size(); 183 if (cnt > 1) { 184 log.warn("More than 1 Access Control Policy found containing composed policy with id = " + composedPolicyId); 185 } 186 187 if (cnt >= 1) { 188 id = (String)ids.get(0); 189 190 rootPolicy = loadPolicy(id); 191 } 192 193 194 return rootPolicy; 195 } 196 197 198 /*** 199 * Loads a policy from the DataHandler, using the specified 200 * <code>PolicyFinder</code> to help with instantiating PolicySets. 201 * 202 * @param DataHandler the DataHandler to load the policy from 203 * @param finder a PolicyFinder used to help in instantiating PolicySets 204 * @param handler an error handler used to print warnings and errors 205 * during parsing 206 * 207 * @return a policy associated with the specified DataHandler 208 * 209 * @throws RegistryException exception thrown if there is a problem reading the DataHandler's input stream 210 */ 211 private static AbstractPolicy loadPolicy(javax.activation.DataHandler dh, com.sun.xacml.finder.PolicyFinder finder) throws RegistryException { 212 213 AbstractPolicy policy = null; 214 try { 215 // create the factory 216 javax.xml.parsers.DocumentBuilderFactory factory = 217 javax.xml.parsers.DocumentBuilderFactory.newInstance(); 218 factory.setIgnoringComments(true); 219 220 javax.xml.parsers.DocumentBuilder db = null; 221 222 // set the factory to work the way the system requires 223 // we're not doing any validation 224 factory.setNamespaceAware(false); 225 factory.setValidating(false); 226 227 db = factory.newDocumentBuilder(); 228 229 // try to load the policy file 230 org.w3c.dom.Document doc = db.parse(dh.getInputStream()); 231 232 // handle the policy, if it's a known type 233 org.w3c.dom.Element root = doc.getDocumentElement(); 234 String name = root.getTagName(); 235 236 if (name.equals("Policy")) { 237 policy = com.sun.xacml.Policy.getInstance(root); 238 } else if (name.equals("PolicySet")) { 239 policy = com.sun.xacml.PolicySet.getInstance(root, finder); 240 } else { 241 // this isn't a root type that we know how to handle 242 throw new RegistryException("unknown root document type: " + name); 243 } 244 245 } catch (Exception e) { 246 e.printStackTrace(); 247 throw new RegistryException(e); 248 } 249 250 return policy; 251 } 252 253 254 /*** 255 * Returns true if the module supports finding policies based on a 256 * request (ie, target matching). By default this method returns false. 257 * 258 * @return true if request retrieval is supported 259 */ 260 public boolean isRequestSupported() { 261 return true; 262 } 263 264 /*** 265 * Returns true if the module supports finding policies based on an 266 * id reference (in a PolicySet). By default this method returns false. 267 * 268 * @return true if idReference retrieval is supported 269 */ 270 public boolean isIdReferenceSupported() { 271 return true; 272 } 273 274 public void init(com.sun.xacml.finder.PolicyFinder finder) { 275 this.finder = finder; 276 } 277 278 private String getRegistryObjectPolicyId(String resourceId) throws RegistryException { 279 String id = null; 280 281 org.oasis.ebxml.registry.bindings.query.ResponseOption responseOption = new org.oasis.ebxml.registry.bindings.query.ResponseOption(); 282 responseOption.setReturnType(org.oasis.ebxml.registry.bindings.query.types.ReturnTypeType.LEAFCLASS); 283 responseOption.setReturnComposedObjects(false); 284 285 String query = "SELECT * from " + 286 pm.mapTableName("ExtrinsicObject") + " eo, " + 287 pm.mapTableName("Association") + " ass " + 288 " WHERE ass.targetObject = '" + resourceId + "' AND ass.associationType = '" + 289 ASSOCIATION_TYPE_ACCESS_CONTROL_POLICY_FOR + "' AND ass.sourceObject = eo.id"; 290 291 ArrayList objectRefs = new ArrayList(); 292 ArrayList al = pm.executeSQLQuery( query, responseOption, "ExtrinsicObject", objectRefs); 293 ArrayList ids = bu.getIdsFromRegistryObjects(al); 294 295 int cnt = ids.size(); 296 if (cnt > 1) { 297 log.warn("More than 1 Access Control Policy found for RegistryObject with id = " + resourceId); 298 } 299 300 if (cnt >= 1) { 301 id = (String)ids.get(0); 302 } 303 304 return id; 305 } 306 307 /*** 308 * Finds a policy based on a request's context. Returns the custom Policy associated with 309 * resource if any, otherwise return the registry's default Policy. 310 * 311 * This will always do a Target match to make sure that the given policy applies. 312 * 313 * 314 * @param context the representation of the request data 315 * 316 * @return the result of trying to find an applicable policy 317 */ 318 public PolicyFinderResult findPolicy(com.sun.xacml.EvaluationCtx context) { 319 AbstractPolicy roPolicy = null; 320 com.sun.xacml.attr.AttributeValue resourceIdAttr = context.getResourceId(); 321 String resourceId = resourceIdAttr.encode(); //??Suggest marshal instead of encode 322 String policyId = null; 323 324 try { 325 policyId = getRegistryObjectPolicyId(resourceId); 326 roPolicy = loadPolicy(policyId); 327 } 328 catch (RegistryException e) { 329 log.error(e); 330 } 331 332 if (roPolicy != null) { 333 MatchResult match = roPolicy.match(context); 334 int result = match.getResult(); 335 336 if (result == MatchResult.INDETERMINATE) { 337 log.warn("INDETERMINATE policy match for object id=" + resourceIdAttr + " and policy id=" + policyId + " status=" + match.getStatus().toString()); 338 } 339 else if (result == MatchResult.MATCH) { 340 return new PolicyFinderResult(roPolicy); 341 } 342 } 343 344 //roPolicy had no MATCH so use defaultPolicy 345 346 // see if we match 347 MatchResult match = defaultPolicy.match(context); 348 int result = match.getResult(); 349 350 // if there was an error, we stop right away 351 if (result == MatchResult.INDETERMINATE) { 352 return new PolicyFinderResult(match.getStatus()); 353 } 354 else if (result == MatchResult.MATCH) { 355 // if we found a policy, return it, otherwise we're N/A 356 if (defaultPolicy != null) { 357 return new PolicyFinderResult(defaultPolicy); 358 } 359 else { 360 return new PolicyFinderResult(); 361 } 362 } 363 else { 364 //Return N/A 365 return new PolicyFinderResult(); 366 } 367 } 368 369 /*** 370 * Tries to find one and only one matching policy given the idReference 371 * First it tries to find a RegistryObject with specified URI as id. 372 * If none is found, it tries to find an ACP with specified URI as 373 * a value for a Slot named "ComposedPolicies". 374 * 375 * 376 * @param idReference an identifier specifying some policy 377 * @param type type of reference (policy or policySet) as identified by 378 * the fields in <code>PolicyReference</code> 379 * 380 * @return the result of looking for a matching policy 381 */ 382 public PolicyFinderResult findPolicy(java.net.URI idReference, int type) { 383 AbstractPolicy policy = null; 384 385 try { 386 String id = idReference.toString(); 387 policy = loadPolicy(id); 388 } 389 catch (RegistryException e) { 390 log.error(e); 391 } 392 393 if (policy == null) { 394 log.warn("findPolicy: Failed to find policy with id=" + idReference); 395 return new PolicyFinderResult(); 396 } 397 else { 398 return new PolicyFinderResult(policy); 399 } 400 } 401 }

This page was automatically generated by Maven