1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.authorization.xacml;
23
24 import org.opencastproject.mediapackage.MediaPackage;
25 import org.opencastproject.security.api.AccessControlEntry;
26 import org.opencastproject.security.api.AccessControlList;
27 import org.opencastproject.util.XmlSafeParser;
28
29 import org.jboss.security.xacml.core.model.policy.ActionMatchType;
30 import org.jboss.security.xacml.core.model.policy.ActionType;
31 import org.jboss.security.xacml.core.model.policy.ActionsType;
32 import org.jboss.security.xacml.core.model.policy.ApplyType;
33 import org.jboss.security.xacml.core.model.policy.AttributeDesignatorType;
34 import org.jboss.security.xacml.core.model.policy.AttributeValueType;
35 import org.jboss.security.xacml.core.model.policy.ConditionType;
36 import org.jboss.security.xacml.core.model.policy.EffectType;
37 import org.jboss.security.xacml.core.model.policy.ObjectFactory;
38 import org.jboss.security.xacml.core.model.policy.PolicyType;
39 import org.jboss.security.xacml.core.model.policy.ResourceMatchType;
40 import org.jboss.security.xacml.core.model.policy.ResourceType;
41 import org.jboss.security.xacml.core.model.policy.ResourcesType;
42 import org.jboss.security.xacml.core.model.policy.RuleType;
43 import org.jboss.security.xacml.core.model.policy.SubjectAttributeDesignatorType;
44 import org.jboss.security.xacml.core.model.policy.TargetType;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import java.io.InputStream;
49 import java.io.StringWriter;
50 import java.util.List;
51
52 import javax.xml.bind.JAXBContext;
53 import javax.xml.bind.JAXBElement;
54 import javax.xml.bind.JAXBException;
55
56
57
58
59 public final class XACMLUtils {
60
61
62 public static final String RULE_COMBINING_ALG
63 = "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides";
64
65 public static final String ACTION_IDENTIFIER = "urn:oasis:names:tc:xacml:1.0:action:action-id";
66
67 public static final String RESOURCE_IDENTIFIER = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
68
69 public static final String SUBJECT_IDENTIFIER = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
70
71 public static final String SUBJECT_ROLE_IDENTIFIER = "urn:oasis:names:tc:xacml:2.0:subject:role";
72
73 public static final String XACML_STRING_EQUAL = "urn:oasis:names:tc:xacml:1.0:function:string-equal";
74
75 public static final String XACML_STRING_IS_IN = "urn:oasis:names:tc:xacml:1.0:function:string-is-in";
76
77 public static final String W3C_STRING = "http://www.w3.org/2001/XMLSchema#string";
78
79 public static final String ISSUER = "matterhorn";
80
81 protected static JAXBContext jBossXacmlJaxbContext;
82
83 private static final Logger logger = LoggerFactory.getLogger(XACMLUtils.class);
84
85
86 static {
87 try {
88 XACMLUtils.jBossXacmlJaxbContext = JAXBContext.newInstance("org.jboss.security.xacml.core.model.policy",
89 PolicyType.class.getClassLoader());
90 } catch (JAXBException e) {
91 throw new RuntimeException(e);
92 }
93 }
94
95
96
97
98 private XACMLUtils() {
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113 public static AccessControlList parseXacml(InputStream xacml) throws XACMLParsingException {
114
115 try {
116 @SuppressWarnings("unchecked")
117 final AccessControlList acl = new AccessControlList();
118 final List<AccessControlEntry> entries = acl.getEntries();
119 final PolicyType policy = ((JAXBElement<PolicyType>) XACMLUtils.jBossXacmlJaxbContext
120 .createUnmarshaller()
121 .unmarshal(XmlSafeParser.parse(xacml)))
122 .getValue();
123
124 for (Object object : policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) {
125 if (!(object instanceof RuleType)) {
126 throw new XACMLParsingException("Object " + object + " of policy " + policy + " is not of type RuleType");
127 }
128 RuleType rule = (RuleType) object;
129 if (rule.getTarget() == null) {
130 if (rule.getRuleId().equals("DenyRule")) {
131 logger.trace("Skipping global deny rule");
132 continue;
133 }
134 throw new XACMLParsingException("Empty rule " + rule + " in policy " + policy);
135 }
136
137 String role = null;
138 String actionForAce = null;
139 try {
140 ActionType action = rule.getTarget().getActions().getAction().get(0);
141 actionForAce = (String) action.getActionMatch().get(0).getAttributeValue().getContent().get(0);
142
143 @SuppressWarnings("unchecked") JAXBElement<ApplyType> apply
144 = (JAXBElement<ApplyType>) rule.getCondition().getExpression();
145 for (JAXBElement<?> element : apply.getValue().getExpression()) {
146 if (element.getValue() instanceof AttributeValueType) {
147 role = (String) ((AttributeValueType) element.getValue()).getContent().get(0);
148 break;
149 }
150 }
151 } catch (Exception e) {
152 throw new XACMLParsingException("Rule " + rule + " of policy " + policy + " could not be parsed", e);
153 }
154 if (role == null) {
155 throw new XACMLParsingException("Unable to find role in rule " + rule + " of policy " + policy);
156 }
157 AccessControlEntry ace = new AccessControlEntry(role, actionForAce, rule.getEffect().equals(EffectType.PERMIT));
158 entries.add(ace);
159 }
160 return acl;
161 } catch (Exception e) {
162 if (e instanceof XACMLParsingException) {
163 throw (XACMLParsingException) e;
164 }
165 throw new XACMLParsingException("XACML could not be parsed", e);
166 }
167 }
168
169
170
171
172
173
174
175
176
177
178
179 public static String getXacml(MediaPackage mediapackage, AccessControlList accessControlList) throws JAXBException {
180 ObjectFactory jbossXacmlObjectFactory = new ObjectFactory();
181 PolicyType policy = new PolicyType();
182 policy.setPolicyId(mediapackage.getIdentifier().toString());
183 policy.setVersion("2.0");
184 policy.setRuleCombiningAlgId(XACMLUtils.RULE_COMBINING_ALG);
185
186
187 TargetType policyTarget = new TargetType();
188 ResourcesType resources = new ResourcesType();
189 ResourceType resource = new ResourceType();
190 ResourceMatchType resourceMatch = new ResourceMatchType();
191 resourceMatch.setMatchId(XACMLUtils.XACML_STRING_EQUAL);
192 AttributeValueType resourceAttributeValue = new AttributeValueType();
193 resourceAttributeValue.setDataType(XACMLUtils.W3C_STRING);
194 resourceAttributeValue.getContent().add(mediapackage.getIdentifier().toString());
195 AttributeDesignatorType resourceDesignator = new AttributeDesignatorType();
196 resourceDesignator.setAttributeId(XACMLUtils.RESOURCE_IDENTIFIER);
197 resourceDesignator.setDataType(XACMLUtils.W3C_STRING);
198
199
200 resourceMatch.setResourceAttributeDesignator(resourceDesignator);
201 resourceMatch.setAttributeValue(resourceAttributeValue);
202 resource.getResourceMatch().add(resourceMatch);
203 resources.getResource().add(resource);
204 policyTarget.setResources(resources);
205 policy.setTarget(policyTarget);
206
207
208 for (AccessControlEntry ace : accessControlList.getEntries()) {
209 boolean allow = ace.isAllow();
210
211 RuleType rule = new RuleType();
212 rule.setRuleId(ace.getRole() + "_" + ace.getAction() + (allow ? "_Permit" : "_Deny"));
213 if (allow) {
214 rule.setEffect(EffectType.PERMIT);
215 } else {
216 rule.setEffect(EffectType.DENY);
217 }
218
219 TargetType target = new TargetType();
220 ActionsType actions = new ActionsType();
221 ActionType action = new ActionType();
222 ActionMatchType actionMatch = new ActionMatchType();
223 actionMatch.setMatchId(XACMLUtils.XACML_STRING_EQUAL);
224 AttributeValueType attributeValue = new AttributeValueType();
225 attributeValue.setDataType(XACMLUtils.W3C_STRING);
226 attributeValue.getContent().add(ace.getAction());
227 AttributeDesignatorType designator = new AttributeDesignatorType();
228 designator.setAttributeId(XACMLUtils.ACTION_IDENTIFIER);
229 designator.setDataType(XACMLUtils.W3C_STRING);
230
231
232 actionMatch.setActionAttributeDesignator(designator);
233 actionMatch.setAttributeValue(attributeValue);
234 action.getActionMatch().add(actionMatch);
235 actions.getAction().add(action);
236 target.setActions(actions);
237 rule.setTarget(target);
238
239 ConditionType condition = new ConditionType();
240 ApplyType apply = new ApplyType();
241 apply.setFunctionId(XACMLUtils.XACML_STRING_IS_IN);
242
243 AttributeValueType conditionAttributeValue = new AttributeValueType();
244 conditionAttributeValue.setDataType(XACMLUtils.W3C_STRING);
245 conditionAttributeValue.getContent().add(ace.getRole());
246
247 SubjectAttributeDesignatorType subjectDesignator = new SubjectAttributeDesignatorType();
248 subjectDesignator.setDataType(XACMLUtils.W3C_STRING);
249 subjectDesignator.setAttributeId(XACMLUtils.SUBJECT_ROLE_IDENTIFIER);
250 apply.getExpression().add(jbossXacmlObjectFactory.createAttributeValue(conditionAttributeValue));
251 apply.getExpression().add(jbossXacmlObjectFactory.createSubjectAttributeDesignator(subjectDesignator));
252
253 condition.setExpression(jbossXacmlObjectFactory.createApply(apply));
254 rule.setCondition(condition);
255 policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
256 }
257
258
259 RuleType deny = new RuleType();
260 deny.setEffect(EffectType.DENY);
261 deny.setRuleId("DenyRule");
262 policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(deny);
263
264
265 StringWriter writer = new StringWriter();
266 XACMLUtils.jBossXacmlJaxbContext.createMarshaller().marshal(jbossXacmlObjectFactory.createPolicy(policy), writer);
267 return writer.getBuffer().toString();
268 }
269
270 }