001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: AuthorizationDecisionStatementBase.java,v 1.2 2008/06/25 05:47:32 qcheng Exp $ 026 * 027 */ 028 029 030package com.sun.identity.saml.assertion; 031 032import java.text.*; 033import java.util.*; 034import org.w3c.dom.*; 035import com.sun.identity.saml.common.SAMLUtilsCommon; 036import com.sun.identity.saml.common.SAMLConstants; 037import com.sun.identity.saml.common.SAMLException; 038import com.sun.identity.saml.common.SAMLRequesterException; 039 040/** 041 * The <code>AuthorizationDecisionStatement</code> element supplies a statement 042 * by the issuer that the request for access by the specified subject to the 043 * specified resource has resulted in the specified decision on the basis of 044 * some optionally specified evidence. 045 * 046 * This class is an abstract base class for all AuthorizationDecisionStatement 047 * implementations and encapsulates common functionality. 048 * @supported.all.api 049 */ 050public abstract class AuthorizationDecisionStatementBase 051 extends SubjectStatement { 052 053/** 054 *The <code>DecisionType</code> is an inner class defining constants for the 055 *type of Decisions than can be conveyed by an 056 *<code>AuthorizationDecisionStatement </code>. 057 *<br>1 implies <code>PERMIT</code> 058 *<br>2 implies <code>DENY</code> 059 *<br>3 implies <code>INDETERMINATE </code> 060 *<br>4 implies <code>NOT_SUPPORTED</code> 061 */ 062 063 public static class DecisionType { 064 /** 065 * The specified action is permitted. 066 */ 067 public static final int PERMIT = 1; 068 069 /** 070 * The specified action is denied. 071 */ 072 public static final int DENY = 2; 073 074 /** 075 * The issuer cannot determine whether the specified action is 076 * permitted or denied. 077 */ 078 public static final int INDETERMINATE = 3; 079 080 /** 081 * The specified action is not supported. 082 */ 083 public static final int NOT_SUPPORTED = -1; 084 } 085 086 private String _resource = null; 087 private int _decision = DecisionType.NOT_SUPPORTED; 088 private List _action = null; 089 protected EvidenceBase _evidence = null; 090 091 /** 092 *Default constructor 093 */ 094 protected AuthorizationDecisionStatementBase() { 095 } 096 097 /** 098 * Constructs an <code>AuthorizationStatement</code> element from an 099 * existing XML block. 100 * 101 * @param element representing a DOM tree element 102 * @exception SAMLException if there is an error in the sender or in 103 * the element definition. 104 */ 105 public AuthorizationDecisionStatementBase(Element element) 106 throws SAMLException { 107 // make sure input is not null 108 if (element == null) { 109 if (SAMLUtilsCommon.debug.messageEnabled()) { 110 SAMLUtilsCommon.debug.message( 111 "AuthorizationDecisionStatement: null input."); 112 } 113 throw new SAMLRequesterException( 114 SAMLUtilsCommon.bundle.getString("nullInput")); 115 } 116 117 // check if it's an AuthorizationDecisionStatement 118 boolean valid = SAMLUtilsCommon.checkStatement(element, 119 "AuthorizationDecisionStatement"); 120 if (!valid) { 121 if (SAMLUtilsCommon.debug.messageEnabled()) { 122 SAMLUtilsCommon.debug.message( 123 "AuthorizationDecisionStatement: Wrong input."); 124 } 125 throw new SAMLRequesterException( 126 SAMLUtilsCommon.bundle.getString("wrongInput")); 127 } 128 129 int i = 0; 130 //handle the attributes of AuthorizationDecisionStatement 131 NamedNodeMap atts = ((Node)element).getAttributes(); 132 int attCount = atts.getLength(); 133 for (i = 0; i < attCount; i++) { 134 Node att = atts.item(i); 135 if (att.getNodeType() == Node.ATTRIBUTE_NODE) { 136 String attName = att.getLocalName(); 137 if (attName == null || attName.length() == 0) { 138 if (SAMLUtilsCommon.debug.messageEnabled()) { 139 SAMLUtilsCommon.debug.message("AuthorizationDecision" + 140 "Statement: Attribute name is either null or empty."); 141 } 142 throw new SAMLRequesterException( 143 SAMLUtilsCommon.bundle.getString("nullInput")); 144 } 145 if (attName.equals("Resource")) { 146 _resource = ((Attr)att).getValue().trim(); 147 if (_resource == null || _resource.length() == 0) { 148 if (SAMLUtilsCommon.debug.messageEnabled()) { 149 SAMLUtilsCommon.debug.message( 150 "AuthorizationDecision" + 151 "Statement: Resource is null or empty."); 152 } 153 throw new SAMLRequesterException( 154 SAMLUtilsCommon.bundle.getString( 155 "missingAttributeValue")); 156 } 157 } else if (attName.equals("Decision")) { 158 String decisionStr = ((Attr)att).getValue().trim(); 159 if (decisionStr == null || decisionStr.length() == 0) { 160 if (SAMLUtilsCommon.debug.messageEnabled()) { 161 SAMLUtilsCommon.debug.message( 162 "AuthorizationDecision" + 163 "Statement: Decision is null or empty."); 164 } 165 throw new SAMLRequesterException( 166 SAMLUtilsCommon.bundle.getString( 167 "missingAttributeValue")); 168 } 169 if (decisionStr.equals("Permit")) 170 _decision = DecisionType.PERMIT; 171 else if (decisionStr.equals("Deny")) 172 _decision = DecisionType.DENY; 173 else if (decisionStr.equals("Indeterminate")) 174 _decision = DecisionType.INDETERMINATE; 175 else { 176 if (SAMLUtilsCommon.debug.messageEnabled()) { 177 SAMLUtilsCommon.debug.message( 178 "AuthorizationDecision" + 179 "Statement: The type of decision is illegal!"); 180 } 181 throw new SAMLRequesterException( 182 SAMLUtilsCommon.bundle.getString("wrongInput")); 183 } 184 } 185 } 186 } // end of for loop 187 188 // Resource is required 189 if (_resource == null || _resource.length() == 0) { 190 if (SAMLUtilsCommon.debug.messageEnabled()) { 191 SAMLUtilsCommon.debug.message( 192 "AuthorizationDecisionStatement: "+ 193 "Resource is required attribute."); 194 } 195 throw new SAMLRequesterException( 196 SAMLUtilsCommon.bundle.getString("missingAttribute")); 197 } 198 // Decision is required 199 if (_decision == DecisionType.NOT_SUPPORTED) { 200 if (SAMLUtilsCommon.debug.messageEnabled()) { 201 SAMLUtilsCommon.debug.message( 202 "AuthorizationDecisionStatement: "+ 203 "Decision is required attribute."); 204 } 205 throw new SAMLRequesterException( 206 SAMLUtilsCommon.bundle.getString("missingAttribute")); 207 } 208 //Handle the children elements of AuthorizationDecisionStatement 209 NodeList nodes = element.getChildNodes(); 210 int nodeCount = nodes.getLength(); 211 if (nodeCount > 0) { 212 for (i = 0; i < nodeCount; i++) { 213 Node currentNode = nodes.item(i); 214 if (currentNode.getNodeType() == Node.ELEMENT_NODE) { 215 String tagName = currentNode.getLocalName(); 216 String tagNS = currentNode.getNamespaceURI(); 217 if ((tagName == null) || tagName.length() == 0 || 218 tagNS == null || tagNS.length() == 0) { 219 if (SAMLUtilsCommon.debug.messageEnabled()) { 220 SAMLUtilsCommon.debug.message( 221 "AuthorizationDecision" + 222 "Statement: The tag name or tag namespace" + 223 " of child element is either null or empty."); 224 } 225 throw new SAMLRequesterException( 226 SAMLUtilsCommon.bundle.getString("nullInput")); 227 } 228 if (tagName.equals("Subject") && 229 tagNS.equals(SAMLConstants.assertionSAMLNameSpaceURI)) { 230 if (this._subject != null) { 231 if (SAMLUtilsCommon.debug.messageEnabled()) { 232 SAMLUtilsCommon.debug.message( 233 "AuthorizationDecisionStatement: "+ 234 " should only contain one subject"); 235 } 236 throw new SAMLRequesterException( 237 SAMLUtilsCommon.bundle.getString("oneElement")); 238 239 } else 240 this._subject = 241 createSubject((Element)currentNode); 242 } else if (tagName.equals("Action") && 243 tagNS.equals(SAMLConstants.assertionSAMLNameSpaceURI)) { 244 if (_action == null) { 245 _action = new ArrayList(); 246 } 247 if (!(_action.add(createAction((Element) 248 currentNode)))) { 249 if (SAMLUtilsCommon.debug.messageEnabled()) { 250 SAMLUtilsCommon.debug.message("Authentication" 251 + "Statment: failed to add to the" 252 + " AuthorityBinding list."); 253 } 254 throw new SAMLRequesterException( 255 SAMLUtilsCommon.bundle.getString( 256 "addListError")); 257 } 258 } else if (tagName.equals("Evidence") && 259 tagNS.equals(SAMLConstants.assertionSAMLNameSpaceURI)) { 260 _evidence = createEvidence((Element)currentNode); 261 } else { 262 if (SAMLUtilsCommon.debug.messageEnabled()) { 263 SAMLUtilsCommon.debug.message( 264 "AuthorizationDecisionStatement: "+ 265 "wrong element:" + tagName); 266 } 267 throw new SAMLRequesterException( 268 SAMLUtilsCommon.bundle.getString("wrongInput")); 269 } 270 } // end of if (currentNode.getNodeType() == Node.ELEMENT_NODE) 271 } // end of for loop 272 } // end of if (nodeCount > 0) 273 274 // check if the subject is null 275 if (this._subject == null) { 276 if (SAMLUtilsCommon.debug.messageEnabled()) { 277 SAMLUtilsCommon.debug.message("AuthorizationDecisionStatement:" 278 + " should contain exactly one subject."); 279 } 280 throw new SAMLRequesterException( 281 SAMLUtilsCommon.bundle.getString("missingElement")); 282 } 283 //check if the Action is null 284 if (_action == null || _action.isEmpty()) { 285 if (SAMLUtilsCommon.debug.messageEnabled()) { 286 SAMLUtilsCommon.debug.message("AuthorizationDecisionStatement:" 287 + " should at least contain one Action."); 288 } 289 throw new SAMLRequesterException( 290 SAMLUtilsCommon.bundle.getString("missingElement")); 291 } 292 } 293 294 /** 295 * Constructs an instance of <code>AuthorizationDecisionStatement</code>. 296 * 297 * @param subject (required) A Subject object 298 * @param resource (required) A String identifying the resource to which 299 * access authorization is sought. 300 * @param decision (required) The decision rendered by the issuer with 301 * respect to the specified resource. The value is of the 302 * <code>DecisionType</code> simple type. 303 * @param action (required) A List of Action objects specifying the set of 304 * actions authorized to be performed on the specified resource. 305 * @param evidence (optional) An Evidence object representing a set of 306 * assertions that the issuer replied on in making decisions. 307 * @exception SAMLException if there is an error in the sender. 308 */ 309 public AuthorizationDecisionStatementBase(Subject subject, String resource, 310 int decision, List action, EvidenceBase evidence) 311 throws SAMLException { 312 // check if the subject is null 313 if (subject == null) { 314 if (SAMLUtilsCommon.debug.messageEnabled()) { 315 SAMLUtilsCommon.debug.message( 316 "AuthorizationDecisionStatement:" + 317 "missing the subject."); 318 } 319 throw new SAMLRequesterException( 320 SAMLUtilsCommon.bundle.getString("missingElement")); 321 } else { 322 this._subject = subject; 323 } 324 325 // Resource is required 326 if (resource == null || resource.length() == 0) { 327 if (SAMLUtilsCommon.debug.messageEnabled()) { 328 SAMLUtilsCommon.debug.message( 329 "AuthorizationDecisionStatement: "+ 330 "resource is required attribute"); 331 } 332 throw new SAMLRequesterException( 333 SAMLUtilsCommon.bundle.getString("missingAttribute")); 334 } else { 335 _resource = resource; 336 } 337 338 // check if the decision is null 339 if (decision < DecisionType.PERMIT || 340 (decision > DecisionType.INDETERMINATE)) { 341 if (SAMLUtilsCommon.debug.messageEnabled()) { 342 SAMLUtilsCommon.debug.message( 343 "AuthorizationDecisionStatement:" + 344 "The type of decision is illegal."); 345 } 346 throw new SAMLRequesterException( 347 SAMLUtilsCommon.bundle.getString("wrongInput")); 348 } else { 349 _decision = decision; 350 } 351 352 // Actions is required 353 if (action == null || action.isEmpty()) { 354 if (SAMLUtilsCommon.debug.messageEnabled()) { 355 SAMLUtilsCommon.debug.message( 356 "AuthorizationDecisionStatement: "+ 357 "Action is required."); 358 } 359 throw new SAMLRequesterException( 360 SAMLUtilsCommon.bundle.getString("missingElement")); 361 } else { 362 if (_action == null) { 363 _action = new ArrayList(); 364 } 365 _action = action; 366 } 367 368 _evidence = evidence; 369 } 370 371 /** 372 * Constructs a <code>AuthorizationDecisionStatement</code> instance. 373 * 374 *@param subject (required) A Subject object 375 *@param resource (required) A String identifying the resource to which 376 * access authorization is sought. 377 *@param decision (required) The decision rendered by the issuer with 378 * respect to the specified resource. The value is of the 379 * <code>DecisionType</code> simple type. 380 *@param action (required) A List of Action objects specifying the set of 381 * actions authorized to be performed on the 382 * specified resource. 383 *@exception SAMLException if there is an error in the sender. 384 */ 385 public AuthorizationDecisionStatementBase(Subject subject, 386 String resource, int decision, List action) throws SAMLException { 387 // check if the subject is null 388 if (subject == null) { 389 if (SAMLUtilsCommon.debug.messageEnabled()) { 390 SAMLUtilsCommon.debug.message( 391 "AuthorizationDecisionStatement:" + 392 "missing the subject."); 393 } 394 throw new SAMLRequesterException( 395 SAMLUtilsCommon.bundle.getString("missingElement")); 396 } else { 397 this._subject = subject; 398 } 399 // Resource is required 400 if (resource == null || resource.length() == 0) { 401 if (SAMLUtilsCommon.debug.messageEnabled()) { 402 SAMLUtilsCommon.debug.message( 403 "AuthorizationDecisionStatement: "+ 404 "resource is required attribute"); 405 } 406 throw new SAMLRequesterException( 407 SAMLUtilsCommon.bundle.getString("missingAttribute")); 408 } else { 409 _resource = resource; 410 } 411 412 // check if the decision is null 413 if (decision <= DecisionType.PERMIT || 414 (decision >= DecisionType.INDETERMINATE)) { 415 if (SAMLUtilsCommon.debug.messageEnabled()) { 416 SAMLUtilsCommon.debug.message( 417 "AuthorizationDecisionStatement:" + 418 "The type of decision is illegal."); 419 } 420 throw new SAMLRequesterException( 421 SAMLUtilsCommon.bundle.getString("wrongInput")); 422 } else { 423 _decision = decision; 424 } 425 // Action is required 426 if (action == null || action.isEmpty()) { 427 if (SAMLUtilsCommon.debug.messageEnabled()) { 428 SAMLUtilsCommon.debug.message( 429 "AuthorizationDecisionStatement: "+ 430 "Action is required."); 431 } 432 throw new SAMLRequesterException( 433 SAMLUtilsCommon.bundle.getString("missingElement")); 434 } else { 435 if (_action == null) { 436 _action = new ArrayList(); 437 } 438 _action = action; 439 } 440 } 441 442 /** 443 * Creates appropriate Evidence Instance 444 * @param evidenceElement the Evidence Element 445 * @return the Evidence Object 446 */ 447 protected abstract EvidenceBase createEvidence(Element evidenceElement) 448 throws SAMLException; 449 450 /** 451 * Creates appropriate Subject Instance 452 * @param subjectElement the Subject Element 453 * @return the Subject Object 454 */ 455 protected abstract Subject createSubject(Element subjectElement) 456 throws SAMLException; 457 458 /** 459 * Creates appropriate Action Instance 460 * @param actionElement the Action Element 461 * @return the Action Object 462 */ 463 protected abstract Action createAction(Element actionElement) 464 throws SAMLException; 465 466 /** 467 * Returns the action(s) from <code>AuthorizationStatement</code>. 468 * 469 * @return A List of Action object(s) specifying the set of actions 470 * authorized to be performed on the specified resource. 471 */ 472 public List getAction() { 473 return _action; 474 } 475 476 /** 477 * Returns the resource from <code>AuthorizationStatement</code> 478 * 479 * @return A String identifying the resource to which access authorization 480 * is sought. 481 */ 482 public String getResource() { 483 return _resource; 484 } 485 486 /** 487 * Returns the decision for <code>AuthorizationStatement</code>. 488 * 489 * @return The decision string such as 490 * <code>permit</code> 491 * <code>deny</code> 492 * <code>indetereminate</code> 493 */ 494 public int getDecision() { 495 return _decision; 496 } 497 498 /** 499 * Returns the real type of statement. This method returns 500 * <code>Statement.AUTHORIZATION_DECISION_STATEMENT</code>. 501 * 502 * @return <code>Statement.AUTHORIZATION_DECISION_STATEMENT</code>. 503 */ 504 public int getStatementType() { 505 return Statement.AUTHORIZATION_DECISION_STATEMENT; 506 } 507 508 /** 509 * Returns a String representation of the 510 * <code>AuthorizationStatement</code>. 511 * 512 * @return A String representation of the 513 * <code><AuthorizationDecisionStatement</code> element. 514 */ 515 public String toString() { 516 return toString(true, false); 517 } 518 519 /** 520 * Returns a String representation of the 521 * <code>AuthorizationStatement</code>. 522 * 523 * @param includeNS Determines whether or not the namespace qualifier is 524 * prepended to the Element when converted 525 * @param declareNS Determines whether or not the namespace is declared 526 * within the Element. 527 * @return A String representation of the 528 * <code><AuthorizationDecisionStatement></code> element. 529 */ 530 public String toString(boolean includeNS, boolean declareNS) { 531 StringBuffer result = new StringBuffer(3000); 532 String prefix = ""; 533 String uri = ""; 534 if (includeNS) { 535 prefix = SAMLConstants.ASSERTION_PREFIX; 536 } 537 if (declareNS) { 538 uri = SAMLConstants.assertionDeclareStr; 539 } 540 result.append("<").append(prefix). 541 append("AuthorizationDecisionStatement"). 542 append(uri).append(" Resource=\"").append(_resource). 543 append("\" Decision=\"").append(decisionTypeConvert(_decision)). 544 append("\">\n"); 545 result.append(this._subject.toString(includeNS, false)); 546 Iterator iter = _action.iterator(); 547 while (iter.hasNext()) { 548 Action act = (Action)iter.next(); 549 result.append(act.toString(includeNS, false)); 550 } 551 552 if (_evidence != null) { 553 result.append(_evidence.toString(includeNS, false)); 554 } 555 result.append("</").append(prefix). 556 append("AuthorizationDecisionStatement>\n"); 557 return(result.toString()); 558 } 559 560 /** 561 *Converts the number to the mapping string 562 *@param number - an int 563 *@return a mapping string 564 */ 565 private String decisionTypeConvert(int number){ 566 String result = ""; 567 switch(number) { 568 case DecisionType.PERMIT : result = "Permit"; break; 569 case DecisionType.DENY: result = "Deny"; break ; 570 case DecisionType.INDETERMINATE: result = "Indeterminate"; break ; 571 } 572 return result; 573 } 574} 575