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: FSAuthenticationStatement.java,v 1.2 2008/06/25 05:46:43 qcheng Exp $ 026 * 027 */ 028 029package com.sun.identity.federation.message; 030 031import com.sun.identity.federation.common.IFSConstants; 032import com.sun.identity.federation.common.FSUtils; 033import com.sun.identity.federation.message.common.AuthnContext; 034import com.sun.identity.federation.message.common.FSMsgException; 035import com.sun.identity.saml.assertion.AuthenticationStatement; 036import com.sun.identity.saml.assertion.AuthorityBinding; 037import com.sun.identity.saml.assertion.Subject; 038import com.sun.identity.saml.assertion.SubjectLocality; 039import com.sun.identity.saml.common.SAMLConstants; 040import com.sun.identity.saml.common.SAMLException; 041import com.sun.identity.shared.DateUtils; 042import java.text.ParseException; 043import java.util.ArrayList; 044import java.util.Date; 045import java.util.Iterator; 046import java.util.List; 047import org.w3c.dom.Attr; 048import org.w3c.dom.Element; 049import org.w3c.dom.NamedNodeMap; 050import org.w3c.dom.Node; 051import org.w3c.dom.NodeList; 052 053/** 054 * The <code>FSAuthenticationStatement</code> element represents an 055 * authentication statement by the issuer that it's subject was authenticated 056 * by a particular means at a particular time. 057 * 058 * @supported.all.api 059 */ 060 061public class FSAuthenticationStatement extends AuthenticationStatement { 062 063 protected Date reauthenticateOnOrAfter; 064 protected String sessionIndex = null; 065 protected AuthnContext _authnContext; 066 protected int minorVersion = IFSConstants.FF_11_PROTOCOL_MINOR_VERSION; 067 068 /** 069 * Default Constructor. 070 */ 071 public FSAuthenticationStatement(){ 072 } 073 074 /** 075 * Constructor to create <code>FSAuthenticationStatement</code> object. 076 * 077 * @param authMethod the Authentication method in the statement. 078 * @param authInstant the authentication date in the statement. 079 * @param subject the Subject in the statement. 080 * @param authnContext the Authentication Context. 081 * @throws FSMsgException if there is error 082 * creating the object. 083 * @throws SAMLException if the version is incorrect. 084 */ 085 public FSAuthenticationStatement( 086 String authMethod, 087 Date authInstant, 088 Subject subject, 089 AuthnContext authnContext 090 ) throws FSMsgException, SAMLException { 091 super(authMethod, authInstant, subject); 092 if (authnContext == null) { 093 if (FSUtils.debug.messageEnabled()) { 094 FSUtils.debug.message("FSAuthenticationStatement: missing" + 095 "AuthnContext"); 096 } 097 } else { 098 this._authnContext = authnContext; 099 } 100 } 101 102 /** 103 * Constructor for create <code>FSAuthenticationStatement</code> object. 104 * 105 * @param authMethod the Authentication method in the statement. 106 * @param authInstant the authentication date in the statement. 107 * @param subject the <code>Subject</code> in the statement. 108 * @param subjectLocality the <code>SubjectLocality</code> in the statement. 109 * @param authorityBinding a List of <code>AuthorityBinding</code> objects. 110 * @param authnContext the Authentication Context. 111 * @throws FSMsgException if there is an error 112 * creating the object. 113 * @throws SAMLException on error. 114 */ 115 public FSAuthenticationStatement( 116 String authMethod, 117 Date authInstant, 118 Subject subject, 119 SubjectLocality subjectLocality, 120 List authorityBinding, 121 AuthnContext authnContext 122 ) throws FSMsgException, SAMLException { 123 super(authMethod, 124 authInstant, 125 subject, 126 subjectLocality, 127 authorityBinding); 128 129 // check if the AuthnContext is null 130 if (authnContext == null) { 131 if (FSUtils.debug.messageEnabled()) { 132 FSUtils.debug.message("FSAuthenticationStatement: missing" + 133 "AuthnContext."); 134 } 135 } else { 136 this._authnContext = authnContext; 137 } 138 } 139 140 /** 141 * Constructs an <code>FSAuthenticationStatement</code> object from a 142 * Document Element. 143 * 144 * @param element the Document Element object. 145 * @throws FSMsgException if document element is null 146 * or required attributes cannot be retrieved from the element. 147 * @throws SAMLException on error. 148 */ 149 public FSAuthenticationStatement(Element element) 150 throws FSMsgException, SAMLException { 151 FSUtils.debug.message("FSAuthenticationStatement(Element): Called"); 152 if (element == null) { 153 FSUtils.debug.message("FSAuthenticationStatement: null input."); 154 throw new FSMsgException("nullInput",null); 155 } 156 int i = 0; 157 //handle the attributes of AuthenticationStatement 158 NamedNodeMap atts = ((Node)element).getAttributes(); 159 int attCount = atts.getLength(); 160 for (i = 0; i < attCount; i++) { 161 Node att = atts.item(i); 162 if (att.getNodeType() == Node.ATTRIBUTE_NODE) { 163 String attName = att.getLocalName(); 164 if (attName == null || attName.length() == 0) { 165 if (FSUtils.debug.messageEnabled()) { 166 FSUtils.debug.message("FSAuthenticationStatement:" + 167 "Attribute name is either null or empty."); 168 } 169 throw new FSMsgException("nullInput", null); 170 } 171 if (attName.equals(IFSConstants.AUTHENTICATION_METHOD)) { 172 _authenticationMethod = ((Attr)att).getValue().trim(); 173 } else if (attName.equals(IFSConstants.AUTHENTICATION_INSTANT)){ 174 try { 175 _authenticationInstant = 176 DateUtils.stringToDate(((Attr)att).getValue()); 177 } catch (ParseException pe ) { 178 FSUtils.debug.error("FSAuthenticationStatement:" + 179 "StringToDate: ", pe); 180 throw new FSMsgException("wrongDateFormat",null); 181 } // end of try...catch 182 } else if (attName.equals(IFSConstants.REAUTH_ON_OR_AFTER)) { 183 try { 184 reauthenticateOnOrAfter = 185 DateUtils.stringToDate(((Attr)att).getValue()); 186 } catch (ParseException pe ) { 187 FSUtils.debug.error("FSAuthenticationStatement:" + 188 "StringToDate: ", pe); 189 throw new FSMsgException("wrongDateFormat",null); 190 } 191 } else if (attName.equals(IFSConstants.SESSION_INDEX)) { 192 sessionIndex = 193 ((Attr)att).getValue().trim(); 194 } 195 } 196 } // end of for loop 197 //Handle the children elements of AuthenticationStatement 198 NodeList nodes = element.getChildNodes(); 199 int nodeCount = nodes.getLength(); 200 if (nodeCount > 0) { 201 for (i = 0; i < nodeCount; i++) { 202 Node currentNode = nodes.item(i); 203 if (currentNode.getNodeType() == Node.ELEMENT_NODE) { 204 String tagName = currentNode.getLocalName(); 205 String tagNS = currentNode.getNamespaceURI(); 206 if ((tagName == null) || tagName.length() == 0 || 207 tagNS == null || tagNS.length() == 0) { 208 if (FSUtils.debug.messageEnabled()) { 209 FSUtils.debug.message("FSAuthenticationStatement: "+ 210 "The tag name or tag namespace of child" + 211 " element is either null or empty."); 212 } 213 throw new FSMsgException("nullInput",null); 214 } 215 if (tagName.equals(IFSConstants.AUTH_SUBJECT)) { 216 if (this._subject != null) { 217 if (FSUtils.debug.messageEnabled()) { 218 FSUtils.debug.message( 219 "FSAuthenticationStatement" + 220 ":should only contain one subject"); 221 } 222 throw new FSMsgException("oneElement",null); 223 } else { 224 this._subject = 225 new FSSubject((Element) currentNode); 226 } 227 } else if (tagName.equals(IFSConstants.SUBJECT_LOCALITY)) { 228 if (_subjectLocality != null) { 229 if (FSUtils.debug.messageEnabled()) { 230 FSUtils.debug.message( 231 "FSAuthenticationStatement"+ 232 "Statement: should at most " + 233 "contain one SubjectLocality."); 234 } 235 throw new FSMsgException("oneElement",null); 236 } else { 237 _subjectLocality = 238 new SubjectLocality((Element)currentNode); 239 } 240 } else if (tagName.equals(IFSConstants.AUTHN_CONTEXT) && 241 (tagNS.equals( 242 IFSConstants.libertyMessageNamespaceURI)|| 243 tagNS.equals(IFSConstants.FF_12_XML_NS))) { 244 245 if (_authnContext != null) { 246 if (FSUtils.debug.messageEnabled()) { 247 FSUtils.debug.message("FSAuthentication"+ 248 "Statement: should not contain more " + 249 "than one AuthnContext element."); 250 } 251 throw new FSMsgException("oneElement",null); 252 } else { 253 _authnContext = 254 new AuthnContext((Element)currentNode); 255 } 256 } else if (tagName.equals(IFSConstants.AUTHORITY_BINDING)) { 257 if (_authorityBinding == null) { 258 _authorityBinding = new ArrayList(); 259 } 260 if ((_authorityBinding.add(new AuthorityBinding( 261 (Element)currentNode))) == false) { 262 if (FSUtils.debug.messageEnabled()) { 263 FSUtils.debug.message( 264 "FSAuthenticationStatement"+ 265 ": failed to add to the" + 266 " AuthorityBinding list."); 267 } 268 throw new FSMsgException("addListError",null); 269 } 270 } else { 271 if (FSUtils.debug.messageEnabled()) { 272 FSUtils.debug.message("FSAuthenticationStatement:"+ 273 "Wrong element " 274 + tagName + "included."); 275 } 276 throw new FSMsgException("wrongInput",null); 277 } 278 } // end of if (currentNode.getNodeType() == Node.ELEMENT_NODE) 279 } // end of for loop 280 } // end of if (nodeCount > 0) 281 // check if the subject is null 282 if (this._subject == null) { 283 if (FSUtils.debug.messageEnabled()) { 284 FSUtils.debug.message("FSAuthenticationStatement should " + 285 "contain one subject."); 286 } 287 throw new FSMsgException("missingElement",null); 288 } 289 FSUtils.debug.message("FSAuthenticationStatement(Element): leaving"); 290 } 291 292 293 /** 294 * Returns the value of <code>SessionIndex</code> attribute. 295 * 296 * @return the value of </code>SessionIndex</code> attribute. 297 * @see #setSessionIndex(String) 298 */ 299 public String getSessionIndex(){ 300 return sessionIndex; 301 } 302 303 /** 304 * Sets the <code>SessionIndex</code> attribute. 305 * 306 * @param sessionIndex the value of <code>SessionIndex</code> attribute. 307 * @see #getSessionIndex 308 */ 309 public void setSessionIndex(String sessionIndex){ 310 this.sessionIndex = sessionIndex; 311 } 312 313 /** 314 * Returns the re-authentication date for this 315 * authentication statement. 316 * 317 * @return the re-authentication date for this object. 318 * @see #setReauthenticateOnOrAfter 319 */ 320 public Date getReauthenticateOnOrAfter(){ 321 return reauthenticateOnOrAfter; 322 } 323 324 /** 325 * Sets re-authentication date for this authentication 326 * statement. 327 * 328 * @param reauthenticateOnOrAfter the date object. 329 * @see #getReauthenticateOnOrAfter 330 */ 331 public void setReauthenticateOnOrAfter(Date reauthenticateOnOrAfter){ 332 this.reauthenticateOnOrAfter = reauthenticateOnOrAfter; 333 } 334 335 /** 336 * Returns the Authentication Context in this 337 * authentication statement. 338 * 339 * @return the Authentication Context object. 340 * @see #setAuthnContext(AuthnContext) 341 */ 342 public AuthnContext getAuthnContext(){ 343 return _authnContext; 344 } 345 346 /** 347 * Sets the Authentication Context object. 348 * 349 * @param authnContext the Authentication Context object. 350 * @see #getAuthnContext 351 */ 352 public void setAuthnContext(AuthnContext authnContext){ 353 this._authnContext = authnContext; 354 } 355 356 /** 357 * Returns the value of <code>MinorVersion</code> attribute. 358 * 359 * @return the value of <code>MinorVersion</code> attribute. 360 * @see #setMinorVersion(int) 361 */ 362 public int getMinorVersion() { 363 return minorVersion; 364 } 365 366 /** 367 * Sets the value of <code>MinorVersion</code> attribute. 368 * 369 * @param version the <code>MinorVersion</code> attribute. 370 * @see #getMinorVersion 371 */ 372 public void setMinorVersion(int version) { 373 minorVersion = version; 374 } 375 376 /** 377 * Returns a String representation of this object. 378 * 379 * @throws FSMsgException if there is an error creating 380 * the string. 381 * @return a String representation of this Object. 382 */ 383 public String toXMLString() throws FSMsgException { 384 return (toXMLString(true, false)); 385 } 386 387 /** 388 * Returns a String representation of this object. 389 * 390 * @param includeNS Determines whether or not the namespace qualifier is 391 * prepended to the Element when converted 392 * @param declareNS Determines whether or not the namespace is declared 393 * within the Element. 394 * @return A string containing the valid XML for this object. 395 * @throws FSMsgException if there is an error creating 396 * the string. 397 */ 398 public String toXMLString(boolean includeNS,boolean declareNS) 399 throws FSMsgException { 400 StringBuffer result = new StringBuffer(1000); 401 String prefix = ""; 402 String libprefix = ""; 403 String uri = ""; 404 String liburi = ""; 405 if (includeNS) { 406 prefix = SAMLConstants.ASSERTION_PREFIX; 407 libprefix = IFSConstants.LIB_PREFIX; 408 } 409 if (declareNS) { 410 if (minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 411 liburi = IFSConstants.LIB_12_NAMESPACE_STRING; 412 } else { 413 liburi = IFSConstants.LIB_NAMESPACE_STRING; 414 } 415 uri = SAMLConstants.assertionDeclareStr; 416 } 417 418 result.append(IFSConstants.LEFT_ANGLE).append(prefix) 419 .append(IFSConstants.AUTHENTICATIONSTATEMENT) 420 .append(uri).append(IFSConstants.SPACE).append(liburi) 421 .append(IFSConstants.SPACE); 422 423 if ((_authenticationMethod != null) && 424 _authenticationMethod.length() != 0) { 425 result.append(IFSConstants.AUTHENTICATION_METHOD).append("=\"") 426 .append(_authenticationMethod).append("\" "); 427 } 428 429 if (_authenticationInstant != null) { 430 result.append(IFSConstants.AUTHENTICATION_INSTANT).append("=\"") 431 .append(DateUtils.toUTCDateFormat(_authenticationInstant)) 432 .append("\" "); 433 } 434 435 if (reauthenticateOnOrAfter != null) { 436 result.append(IFSConstants.REAUTH_ON_OR_AFTER).append("=\"") 437 .append(DateUtils.toUTCDateFormat(reauthenticateOnOrAfter)) 438 .append("\" "); 439 } 440 441 if (sessionIndex != null) { 442 result.append(IFSConstants.SESSION_INDEX).append("=\"") 443 .append(sessionIndex).append("\" "); 444 } 445 446 result.append("xsi:type") 447 .append("=\"") 448 .append(libprefix) 449 .append(IFSConstants.AUTHENTICATIONSTATEMENT_TYPE) 450 .append(IFSConstants.QUOTE) 451 .append(IFSConstants.RIGHT_ANGLE); 452 453 if (getSubject() != null) { 454 result.append( 455 ((FSSubject)getSubject()).toXMLString(includeNS, false)); 456 } 457 458 if (_subjectLocality != null) { 459 result.append(_subjectLocality.toString(includeNS, false)); 460 } 461 462 if ((_authorityBinding != null) && (!_authorityBinding.isEmpty())) { 463 Iterator iter = this.getAuthorityBinding().iterator(); 464 while (iter.hasNext()) { 465 AuthorityBinding authBinding = 466 (AuthorityBinding)iter.next(); 467 result.append(authBinding.toString(includeNS, false)); 468 } 469 } 470 if (_authnContext != null) { 471 result.append(_authnContext.toXMLString(includeNS, false)); 472 } 473 result.append(IFSConstants.START_END_ELEMENT).append(prefix) 474 .append(IFSConstants.AUTHENTICATIONSTATEMENT) 475 .append(IFSConstants.RIGHT_ANGLE); 476 return(result.toString()); 477 } 478}