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: AuthenticationStatement.java,v 1.3 2008/06/25 05:47:31 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.shared.DateUtils; 036import com.sun.identity.saml.common.SAMLUtilsCommon; 037import com.sun.identity.saml.common.SAMLConstants; 038import com.sun.identity.saml.common.SAMLException; 039import com.sun.identity.saml.common.SAMLRequesterException; 040 041/** 042 * The <code>AuthenticationStatement</code> element supplies a 043 * statement by the issuer that its subject was authenticated by a 044 * particular means at a particular time. The 045 * <code>AuthenticationStatement</code> element is of type 046 * <code>AuthenticationStatementType</code>, which extends the 047 * <code>SubjectStatementAbstractType</code> with the additional element and 048 * attributes. 049 * @supported.all.api 050 */ 051public class AuthenticationStatement extends SubjectStatement { 052 //The AuthenticationMethod attribute specifies the type of Authentication 053 //that took place. 054 protected String _authenticationMethod = null; 055 056 //The AuthenticationInstant attribute specifies the time at which the 057 //authentication took place. 058 protected Date _authenticationInstant = null; 059 060 //The SubjectLocality specifies the DNS domain name and IP address 061 //for the system entity from which the Subject was apparently authenticated. 062 protected SubjectLocality _subjectLocality = null ; 063 064 //The authority binding specifies the type of authority that performed 065 //the authentication. 066 protected List _authorityBinding = null; 067 068 /** 069 *Default constructor 070 */ 071 protected AuthenticationStatement() { 072 } 073 074 /** 075 * Constructs an authentication statement element from an 076 * existing XML block. 077 * 078 * @param element representing a DOM tree element. 079 * @exception SAMLException if there is an error in the sender or in the 080 * element definition. 081 */ 082 public AuthenticationStatement(Element element) throws SAMLException { 083 // make sure input is not null 084 if (element == null) { 085 SAMLUtilsCommon.debug.message( 086 "AuthenticationStatement: null input."); 087 throw new SAMLRequesterException( 088 SAMLUtilsCommon.bundle.getString("nullInput")); 089 } 090 // check if it's an AuthenticationStatement 091 boolean valid = SAMLUtilsCommon.checkStatement(element, 092 "AuthenticationStatement"); 093 if (!valid) { 094 SAMLUtilsCommon.debug.message( 095 "AuthenticationStatement: Wrong input."); 096 throw new SAMLRequesterException( 097 SAMLUtilsCommon.bundle.getString("wrongInput")); 098 } 099 100 int i = 0; 101 //handle the attributes of AuthenticationStatement 102 NamedNodeMap atts = ((Node)element).getAttributes(); 103 int attCount = atts.getLength(); 104 for (i = 0; i < attCount; i++) { 105 Node att = atts.item(i); 106 if (att.getNodeType() == Node.ATTRIBUTE_NODE) { 107 String attName = att.getLocalName(); 108 if (attName == null || attName.length() == 0) { 109 if (SAMLUtilsCommon.debug.messageEnabled()) { 110 SAMLUtilsCommon.debug.message( 111 "AuthenticationStatement:" + 112 "Attribute name is either null or empty."); 113 } 114 continue; 115 //throw new SAMLRequesterException( 116 // SAMLUtilsCommon.bundle.getString("nullInput")); 117 } 118 if (attName.equals("AuthenticationMethod")) { 119 _authenticationMethod = ((Attr)att).getValue().trim(); 120 } else if (attName.equals("AuthenticationInstant")) { 121 try { 122 _authenticationInstant = 123 DateUtils.stringToDate(((Attr)att).getValue()); 124 } catch (ParseException pe ) { 125 SAMLUtilsCommon.debug.error( 126 "AuthenticationStatement:StringToDate", pe); 127 throw new SAMLRequesterException( 128 SAMLUtilsCommon.bundle.getString( 129 "wrongDateFormat")); 130 } // end of try...catch 131 } 132 } 133 } // end of for loop 134 //Handle the children elements of AuthenticationStatement 135 NodeList nodes = element.getChildNodes(); 136 int nodeCount = nodes.getLength(); 137 if (nodeCount > 0) { 138 for (i = 0; i < nodeCount; i++) { 139 Node currentNode = nodes.item(i); 140 if (currentNode.getNodeType() == Node.ELEMENT_NODE) { 141 String tagName = currentNode.getLocalName(); 142 String tagNS = currentNode.getNamespaceURI(); 143 if ((tagName == null) || tagName.length() == 0 || 144 tagNS == null || tagNS.length() == 0) { 145 if (SAMLUtilsCommon.debug.messageEnabled()) { 146 SAMLUtilsCommon.debug.message( 147 "AuthenticationStatement: The" + 148 " tag name or tag namespace of child" + 149 " element is either null or empty."); 150 } 151 throw new SAMLRequesterException( 152 SAMLUtilsCommon.bundle.getString("nullInput")); 153 } 154 if (tagName.equals("Subject") && 155 tagNS.equals(SAMLConstants.assertionSAMLNameSpaceURI)) { 156 if (this._subject != null) { 157 if (SAMLUtilsCommon.debug.messageEnabled()) { 158 SAMLUtilsCommon.debug.message("Authentication" + 159 "Statement:should only contain one subject"); 160 } 161 throw new SAMLRequesterException( 162 SAMLUtilsCommon.bundle.getString("oneElement")); 163 } else { 164 this._subject = 165 createSubject((Element)currentNode); 166 } 167 } else if (tagName.equals("SubjectLocality") && 168 tagNS.equals(SAMLConstants.assertionSAMLNameSpaceURI)) { 169 if (_subjectLocality != null) { 170 if (SAMLUtilsCommon.debug.messageEnabled()) { 171 SAMLUtilsCommon.debug.message("Authentication"+ 172 "Statement: should at most " + 173 "contain one SubjectLocality."); 174 } 175 throw new SAMLRequesterException( 176 SAMLUtilsCommon.bundle.getString( 177 "oneElement")); 178 } else { 179 _subjectLocality = 180 createSubjectLocality((Element)currentNode); 181 } 182 } else if (tagName.equals("AuthorityBinding") && 183 tagNS.equals(SAMLConstants.assertionSAMLNameSpaceURI)) { 184 if (_authorityBinding == null) { 185 _authorityBinding = new ArrayList(); 186 } 187 if ((_authorityBinding.add(createAuthorityBinding( 188 (Element)currentNode))) == false) { 189 if (SAMLUtilsCommon.debug.messageEnabled()) { 190 SAMLUtilsCommon.debug.message( 191 "Authentication Statment: failed to" + 192 " add to the AuthorityBinding list."); 193 } 194 throw new SAMLRequesterException( 195 SAMLUtilsCommon.bundle.getString( 196 "addListError")); 197 } 198 } else { 199 if (SAMLUtilsCommon.debug.messageEnabled()) { 200 SAMLUtilsCommon.debug.message( 201 "AuthenticationStatement:"+ 202 "Wrong element " + tagName + "included."); 203 } 204 throw new SAMLRequesterException( 205 SAMLUtilsCommon.bundle.getString("wrongInput")); 206 } 207 } // end of if (currentNode.getNodeType() == Node.ELEMENT_NODE) 208 } // end of for loop 209 } // end of if (nodeCount > 0) 210 211 // check if the subject is null 212 if (this._subject == null) { 213 if (SAMLUtilsCommon.debug.messageEnabled()) { 214 SAMLUtilsCommon.debug.message( 215 "AuthenticationStatement should " + 216 "contain one subject."); 217 } 218 throw new SAMLRequesterException( 219 SAMLUtilsCommon.bundle.getString("missingElement")); 220 } 221 } 222 223 /** 224 * Constructs <code>Authentication statement</code> 225 * 226 * @param authMethod (optional) A String specifies the type of 227 * authentication that took place. 228 * @param authInstant (optional) A String specifies the time at which 229 * the authentication took place. 230 * @param subject (required) A Subject object 231 * @exception SAMLException if there is an error in the sender. 232 */ 233 public AuthenticationStatement(String authMethod, Date authInstant, 234 Subject subject) throws SAMLException { 235 _authenticationMethod = authMethod; 236 _authenticationInstant = authInstant; 237 238 // check if the subject is null 239 if (subject == null) { 240 if (SAMLUtilsCommon.debug.messageEnabled()) { 241 SAMLUtilsCommon.debug.message( 242 "AuthenticationStatement:missing the subject."); 243 } 244 throw new SAMLRequesterException( 245 SAMLUtilsCommon.bundle.getString("missingElement")); 246 } else 247 this._subject = subject; 248 } 249 250 /** 251 * Constructs <code>AuthenticationStatement</code> 252 * 253 * @param authMethod (optional) A String specifies the type of 254 * authentication that took place. 255 * @param authInstant (optional) A String specifies the time at which the 256 * authentication that took place. 257 * @param subject (required) A Subject object 258 * @param subjectLocality (optional) A <code>SubjectLocality</code> object. 259 * @param authorityBinding (optional) A List of 260 * <code>AuthorityBinding</code> objects. 261 * @exception SAMLException if there is an error in the sender. 262 */ 263 public AuthenticationStatement(String authMethod, Date authInstant, 264 Subject subject, SubjectLocality subjectLocality, 265 List authorityBinding) throws SAMLException { 266 _authenticationMethod = authMethod; 267 _authenticationInstant = authInstant; 268 // check if the subject is null 269 if (subject == null) { 270 if (SAMLUtilsCommon.debug.messageEnabled()) { 271 SAMLUtilsCommon.debug.message( 272 "AuthenticationStatement: should" + 273 " contain one subject."); 274 } 275 throw new SAMLRequesterException( 276 SAMLUtilsCommon.bundle.getString("oneElement")); 277 } else { 278 this._subject = subject; 279 } 280 _subjectLocality = subjectLocality; 281 282 if (authorityBinding != null && !authorityBinding.isEmpty()) { 283 if (_authorityBinding == null) { 284 _authorityBinding = new ArrayList(); 285 } 286 _authorityBinding = authorityBinding; 287 } 288 } 289 290 /** 291 * Returns the <code>SubjectLocality</code> from 292 * <code>AuthenticationStatement</code> 293 * 294 * @return The <code>SubjectLocality</code> object within the authentication 295 * statement. 296 */ 297 public SubjectLocality getSubjectLocality() { 298 return _subjectLocality ; 299 } 300 301 /** 302 * Sets the <code>SubjectLocality</code> for 303 * <code>AuthenticationStatement</code>. 304 * 305 * @param subjectlocality The <code>SubjectLocality</code> object within 306 * the <code>AuthenticationStatement</code>. 307 * @return true if the operation is successful. 308 */ 309 public boolean setSubjectLocality(SubjectLocality subjectlocality) { 310 if (subjectlocality == null) { 311 if (SAMLUtilsCommon.debug.messageEnabled()) { 312 SAMLUtilsCommon.debug.message("AuthenticationStatement: " + 313 "setSubjectLocality:Input is null."); 314 } 315 return false; 316 } 317 _subjectLocality = subjectlocality ; 318 return true; 319 } 320 321 /** 322 * Returns <code>AuthenticationMethod</code> from authentication statement 323 * @return A String representing the authentication method of the 324 * authentication statement. 325 */ 326 public String getAuthenticaionMethod() { 327 return _authenticationMethod; 328 } 329 330 /** 331 * Sets <code>AuthenticationMethod</code> for 332 * <code>AuthenticationStatement</code>. 333 * 334 * @param authenticationmethod input authentication method 335 * @return true if the operation is successful. Otherwise return false. 336 */ 337 public boolean setAuthenticaionMethod(String authenticationmethod) { 338 if (authenticationmethod == null || 339 authenticationmethod.length() == 0) { 340 if (SAMLUtilsCommon.debug.messageEnabled()) { 341 SAMLUtilsCommon.debug.message("AuthenticationStatement: " + 342 "setAuthenticationMethod:Input is null."); 343 } 344 return false; 345 } 346 _authenticationMethod = authenticationmethod; 347 return true; 348 } 349 350 /** 351 * Returns <code>AuthenticationInstant</code> from authentication statement. 352 * @return The date/time when the authentication statement is created. 353 */ 354 public Date getAuthenticationInstant() { 355 return _authenticationInstant; 356 } 357 358 /** 359 * Sets <code>AuthenticationInstant</code> for 360 * <code>AuthenticationStatement</code>. 361 * 362 * @param authenticationinstant The date/time when the authentication 363 * statement is created. 364 * @return true if the operation is successful. 365 */ 366 public boolean setAuthenticationInstant(Date authenticationinstant) { 367 if (authenticationinstant == null) { 368 if (SAMLUtilsCommon.debug.messageEnabled()) { 369 SAMLUtilsCommon.debug.message("AuthenticationStatement: " + 370 "setAuthenticationInstant:Input is null."); 371 } 372 return false; 373 } 374 _authenticationInstant = authenticationinstant; 375 return true; 376 } 377 378 /** 379 * Returns the <code>AuthorityBinding</code> from 380 * <code>AuthenticationStatement</code>. 381 * 382 * @return A list of the <code>AuthorityBinding</code> objects 383 */ 384 public List getAuthorityBinding() { 385 return _authorityBinding; 386 } 387 388 /** 389 * Sets the <code>AuthorityBinding</code> for 390 * <code>AuthenticationStatement</code>. 391 * 392 * @param authoritybinding A list of the <code>AuthorityBinding</code> 393 * objects. 394 * @return true if the operation is successful. 395 */ 396 public boolean setAuthorityBinding(List authoritybinding) { 397 if (authoritybinding == null || authoritybinding.isEmpty()) { 398 if (SAMLUtilsCommon.debug.messageEnabled()) { 399 SAMLUtilsCommon.debug.message("AuthenticationStatement: " + 400 "setAuthorityBinding:Input is null."); 401 } 402 return false; 403 } 404 _authorityBinding = authoritybinding; 405 return true; 406 } 407 408 /** 409 *Gets the real type of the Statement. 410 *This method returns Statement.AUTHENTICATION_STATEMENT. 411 *@return an integer which is Statement.AUTHENTICATION_STATEMENT. 412 */ 413 public int getStatementType() { 414 return Statement.AUTHENTICATION_STATEMENT; 415 } 416 417 /** 418 * Returns a String representation of the Authentication Statement. 419 * 420 * @return A String representation of the 421 * <code><saml:AuthenticationStatement></code> 422 * element. 423 */ 424 public String toString() { 425 return (toString(true, false)); 426 } 427 428 /** 429 * Returns a String representation of the 430 * <code>AuthenticationStatement</code> 431 * @param includeNS Determines whether or not the namespace qualifier is 432 * prepended to the Element when converted 433 * @param declareNS Determines whether or not the namespace is declared 434 * within the Element. 435 * @return A String representation of the 436 * <code><saml:AuthenticationStatement></code> element. 437 */ 438 public String toString(boolean includeNS, boolean declareNS) { 439 StringBuffer result = new StringBuffer(1000); 440 String prefix = ""; 441 String uri = ""; 442 if (includeNS) { 443 prefix = SAMLConstants.ASSERTION_PREFIX; 444 } 445 if (declareNS) { 446 uri = SAMLConstants.assertionDeclareStr; 447 } 448 result.append("<").append(prefix).append("AuthenticationStatement"). 449 append(uri); 450 451 if (_authenticationMethod != null && 452 _authenticationMethod.length() != 0){ 453 result.append(" AuthenticationMethod=\""). 454 append(_authenticationMethod).append("\""); 455 } 456 457 if (_authenticationInstant != null && 458 _authenticationInstant.toString().length() != 0 459 ) { 460 result.append(" AuthenticationInstant=\"") 461 .append(DateUtils.toUTCDateFormat(_authenticationInstant)) 462 .append("\""); 463 } 464 465 result.append(">\n").append(this._subject.toString(includeNS, false)); 466 if (_subjectLocality != null) { 467 result.append(_subjectLocality.toString(includeNS, false)); 468 } 469 if (_authorityBinding != null && !_authorityBinding.isEmpty()) { 470 Iterator iter = this.getAuthorityBinding().iterator(); 471 while (iter.hasNext()) { 472 AuthorityBinding authBinding= 473 (AuthorityBinding)iter.next(); 474 result.append(authBinding.toString(includeNS, false)); 475 } 476 } 477 result.append("</").append(prefix).append("AuthenticationStatement>\n"); 478 return(result.toString()); 479 } 480 481 protected Subject createSubject(Element subjectElement) 482 throws SAMLException { 483 return new Subject(subjectElement); 484 } 485 486 protected SubjectLocality createSubjectLocality( 487 Element subjectLocalityElement) 488 throws SAMLException { 489 return new SubjectLocality(subjectLocalityElement); 490 } 491 492 protected AuthorityBinding createAuthorityBinding( 493 Element authorityBindingElement) throws SAMLException { 494 return new AuthorityBinding(authorityBindingElement); 495 } 496}