001/* 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2005 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: AuthContext.java,v 1.10 2009/01/28 05:34:52 ww203982 Exp $ 026 * 027 * Portions Copyrighted 2011-2015 ForgeRock AS. 028 */ 029 030package com.sun.identity.authentication.internal; 031 032 033import static org.forgerock.openam.ldap.LDAPUtils.isDN; 034import static org.forgerock.openam.ldap.LDAPUtils.rdnValueFromDn; 035 036import javax.security.auth.callback.Callback; 037import javax.security.auth.callback.ChoiceCallback; 038import javax.security.auth.callback.NameCallback; 039import javax.security.auth.callback.PasswordCallback; 040import javax.security.auth.callback.TextInputCallback; 041import javax.security.auth.callback.TextOutputCallback; 042import javax.security.auth.login.LoginException; 043import java.net.InetAddress; 044import java.security.Principal; 045import java.security.SecureRandom; 046import java.util.Iterator; 047import java.util.Set; 048 049import com.iplanet.am.util.SecureRandomManager; 050import com.iplanet.am.util.SystemProperties; 051import com.iplanet.services.util.I18n; 052import com.iplanet.sso.SSOToken; 053import com.sun.identity.authentication.internal.server.AuthSPrincipal; 054import com.sun.identity.authentication.internal.util.AuthI18n; 055import com.sun.identity.shared.Constants; 056import com.sun.identity.shared.debug.Debug; 057import com.sun.identity.sm.ServiceManager; 058import org.forgerock.i18n.LocalizedIllegalArgumentException; 059import org.forgerock.opendj.ldap.DN; 060 061 062/** 063 * The AuthContext provides the implementation for authenticating users using 064 * the JAAS technology. It complements <code>LoginContext 065 * </code> provided by 066 * JAAS by supporting organization environments that cannot handle sessions, for 067 * example, HTTP/HTML. 068 * <p> 069 * A typical caller instantiates this class and starts the login process. The 070 * caller then obtains an array of <code>Callback</code> objects, which 071 * contains the information required by the authentication plug-in module. The 072 * caller requests information from the user. On receiving the information from 073 * the user, the caller submits the same to this class. If more information is 074 * required, the above process continues until all the information required by 075 * the plug-ins has been supplied. The caller then checks if the user has 076 * successfully been authenticated. If successfully authenticated, the caller 077 * can then get the <code> 078 * Subject</code> for the user; if not successfully 079 * authenticated, the caller obtains the LoginException. 080 * 081 * @supported.api 082 */ 083public final class AuthContext extends Object { 084 085 /** 086 * This login status indicates that the login process 087 * has not started yet. Basically, it means that the method 088 * <code>startLogin</code> has not been called. 089 * 090 * @supported.api 091 */ 092 public static final int AUTH_NOT_STARTED = 1; 093 094 /** 095 * This login status indicates that the login process 096 * is in progress. Basically, it means that the <code>startLogin</code> 097 * method has been called and that this object is waiting for the user to 098 * send authentication information. 099 * 100 * @supported.api 101 */ 102 public static final int AUTH_IN_PROGRESS = 2; 103 104 /** 105 * This login status indicates that the login process 106 * has succeeded. 107 * 108 * @supported.api 109 */ 110 public static final int AUTH_SUCCESS = 3; 111 112 /** 113 * This login status indicates that the login process 114 * has failed. 115 * 116 * @supported.api 117 */ 118 public static final int AUTH_FAILED = 4; 119 120 /** 121 * This login status indicates that the user has been 122 * successfully logged out. 123 * 124 * @supported.api 125 */ 126 public static final int AUTH_COMPLETED = 5; 127 128 /* 129 * Protected variables used locally 130 */ 131 protected final String authComponentName = "Authentication"; 132 133 protected final static String authKeyName = "authContext"; 134 135 // Debug class 136 protected final static String authDebugName = "amAuthInternal"; 137 138 protected static Debug authDebug = Debug.getInstance(authDebugName); 139 140 protected String organizationName = null; 141 142 protected String applicationName = null; 143 144 protected int loginStatus; 145 146 protected LoginException loginException; 147 148 protected Callback[] informationRequired; 149 150 protected Callback[] submittedInformation; 151 152 protected AuthLoginThread loginThread; 153 154 protected LoginContext loginContext; 155 156 protected SSOToken token; 157 158 protected static I18n myAuthI18n = AuthI18n.authI18n; 159 160 private static boolean isEnableHostLookUp = Boolean.valueOf( 161 SystemProperties.get(Constants.ENABLE_HOST_LOOKUP)).booleanValue(); 162 163 // 164 // overall, AuthContext is a "conduit" between the application and the 165 // login module. the Principal implementation must be agreed upon at 166 // those two endpoints; AuthContext just passes the Subject that contains 167 // the Principal(s). 168 // 169 170 /** 171 * Constructor to get an instance of 172 * <code>AuthContext</code>. Caller would then use 173 * <code>getRequirements()</code> and <code>submitRequirements()</code> 174 * to pass the credentials needed for authentication by the plugin modules. 175 * 176 * @throws LoginException 177 * 178 * @supported.api 179 */ 180 public AuthContext() throws LoginException { 181 // initialize 182 this(""); 183 } 184 185 /** 186 * Constructor to get an authenticated instance 187 * of this class given the <code>java.security.Principal</code> the user 188 * would like to be authenticated as, and the <code>password</code> for 189 * the user. 190 * 191 * @param principal 192 * name of the user to be authenticated 193 * @param password 194 * password for the user 195 * @throws LoginException 196 * 197 * @supported.api 198 */ 199 public AuthContext(Principal principal, char[] password) 200 throws LoginException { 201 this(null, principal, password); 202 } 203 204 /* 205 * Constructor for DPro to provide hostname and port for LDAP 206 * authentication. 207 */ 208 public AuthContext(Principal principal, char[] password, String hostname, 209 int port) throws LoginException { 210 this(LoginContext.LDAP_AUTH_URL + hostname + ":" + port, principal, 211 password); 212 } 213 214 /** 215 * Constructor to get an instance of this class 216 * given the organization name <code>orgName</code> the user would like to 217 * access, the <code>java.security.Principal 218 * </code>the user would like to 219 * be authenticated as, and the <code>password</code> for the user. 220 * 221 * @param orgName 222 * name of the user's organization 223 * @param principal 224 * name of the user to be authenticated 225 * @param password 226 * password for the user 227 * @throws LoginException 228 * 229 * @supported.api 230 */ 231 public AuthContext(String orgName, Principal principal, char[] password) 232 throws LoginException { 233 // Make sure principal and password are not null 234 if (principal == null) 235 throw (new LoginException(myAuthI18n 236 .getString("com.iplanet.auth.invalid-username"))); 237 if (password == null) 238 throw (new LoginException(myAuthI18n 239 .getString("com.iplanet.auth.invalid-password"))); 240 241 AuthSubject subject = new AuthSubject(); 242 243 if (orgName != null) 244 organizationName = orgName; 245 reset(subject); 246 247 // Set the username and password in LoginContext's sharedState 248 loginContext.updateSharedState(principal.getName(), password); 249 250 boolean gotName = false; 251 boolean gotPassword = false; 252 Callback[] callbacks; 253 254 if (authDebug.messageEnabled()) { 255 authDebug.message("Instantiated AuthContext with parameters " 256 + "organization name: " 257 + organizationName 258 + "; " 259 + ((principal == null) ? "principal is null" 260 : "principal: ") 261 + principal 262 + "; " 263 + ((password.length == 0) ? "password is empty\n" 264 : "password present\n")); 265 } 266 this.startLogin(); 267 268 // 269 // assume that there are requirements, and they are NameCallback and 270 // PasswordCallback. then submit those. 271 // 272 while (this.hasMoreRequirements()) { 273 authDebug.message("AuthContext::init() Has requirements"); 274 callbacks = this.getRequirements(); 275 for (int i = 0; i < callbacks.length; i++) { 276 if (callbacks[i] instanceof NameCallback) { 277 authDebug.message("Got NameCallback"); 278 NameCallback nc = (NameCallback) callbacks[i]; 279 Set sops = subject.getPrincipals(); 280 AuthSPrincipal[] aps = (AuthSPrincipal[]) sops 281 .toArray(new AuthSPrincipal[0]); 282 if (aps.length == 1) { 283 nc.setName(aps[0].getName()); 284 authDebug.message("Set namecallback name = " 285 + aps[0].getName()); 286 gotName = true; 287 } 288 } else if (callbacks[i] instanceof PasswordCallback) { 289 authDebug.message("Got PasswordCallback"); 290 PasswordCallback pc = (PasswordCallback) callbacks[i]; 291 pc.setPassword(password); 292 gotPassword = true; 293 } else if (callbacks[i] instanceof TextOutputCallback) { 294 authDebug.message( 295 "AuthContext::init() Got TextOutputCallback"); 296 } else if (callbacks[i] instanceof TextInputCallback) { 297 authDebug.message( 298 "AuthContext::init() Got TextInputCallback"); 299 } else if (callbacks[i] instanceof ChoiceCallback) { 300 authDebug.message("AuthContext::init() Got ChoiceCallback"); 301 ChoiceCallback cc = (ChoiceCallback) callbacks[i]; 302 cc.setSelectedIndex(0); 303 } else { 304 authDebug.message( 305 "AuthContext::init() Got Unknown Callback"); 306 } 307 308 } 309 this.submitRequiredInformation(callbacks); 310 } 311 312 // Debug messages 313 if (authDebug.messageEnabled() && gotName && gotPassword) { 314 authDebug.message( 315 "AuthContext::init() Got name and password callbacks"); 316 } 317 if (authDebug.messageEnabled()) { 318 authDebug.message("AuthContext::init() Login status: " 319 + this.getLoginStatus()); 320 } 321 322 // Check login status 323 if (getLoginStatus() == AUTH_FAILED) { 324 throw (getLoginException()); 325 } 326 } 327 328 /** 329 * Constructor to get an instance of this class given the organization name 330 * <code>orgName</code> the user would like to access, and the principal's 331 * <code>subject</code> the user would like to be authenticated as. 332 */ 333 protected AuthContext(String orgName, AuthSubject subject) 334 throws LoginException { 335 String orgname = orgName; 336 337 if (authDebug.messageEnabled()) { 338 authDebug.message("Instantiating AuthContext with parameters " 339 + "organization name: " 340 + orgName 341 + "; " 342 + ((subject == null) ? "subject is null" : "subject: " 343 + subject)); 344 } 345 346 if (orgName != null) { 347 if (orgName.startsWith("auth://")) { 348 int i2, offset; 349 String subsample; 350 String appName = null; 351 352 offset = 7; // char count of "auth://" 353 subsample = orgName.substring(offset); 354 // the org + appname, supposedly 355 i2 = subsample.indexOf("/"); 356 if (i2 != -1) { 357 // 358 // from offset to i2 should be the orgName 359 // 360 orgname = subsample.substring(0, i2); 361 authDebug.message("AuthContext::init() auth:// " 362 + "form, orgname = " + orgname); 363 364 // 365 // get past the "/" after the orgName; look for appName 366 // 367 subsample = subsample.substring(i2 + 1); 368 if (subsample.length() > 0) { 369 // 370 // the next check could be for a "?", this is for 371 // possible 372 // future use where parameters such as 373 // "?userid=<userid>&password=<pswd>" could be passed 374 // 375 i2 = subsample.indexOf("?"); 376 if (i2 != -1) { 377 // 378 // parameters specified; pick off appName first 379 // 380 appName = subsample.substring(0, i2); 381 382 // 383 // the rest assumes the userid and password 384 // parameters as 385 // described above. To be implmented 386 // 387 // subsample = subsample.substring(i2+1); 388 } else { 389 // 390 // Only appName was provided, no user name and 391 // password 392 // 393 appName = subsample; 394 } 395 } else { 396 // 397 // no appName, just OrgName and "/" at the end 398 // 399 appName = null; 400 } 401 } else { 402 // 403 // means just the orgName was specified 404 // 405 orgname = subsample; 406 } 407 if (appName != null) { 408 applicationName = appName; 409 } 410 } else if (orgName.startsWith("local://")) { 411 authDebug.message("local form AuthContext specified; " 412 + orgName); 413 int offset = 8; // char count of "local://" 414 orgname = orgName.substring(offset); // just the org, 415 // hopefully 416 } 417 } 418 419 this.organizationName = orgname; 420 reset(subject); 421 } 422 423 // An alternate form of the <code>orgName</code> is 424 // "auth://<orgName>/<appName>" 425 // 426 // note that a private form of orgName is 427 // "local://...". this is for administrative-type 428 // configuration information for install commands, 429 // for example. 430 // 431 /** 432 * Constructor to get an instance of this class 433 * given the organization name <code>orgName</code>. The plug-in modules 434 * would then query for the user name and related information. 435 * 436 * @param orgName organization name. 437 * @throws LoginException 438 * 439 * @supported.api 440 */ 441 public AuthContext(String orgName) throws LoginException { 442 this(orgName, null); 443 authDebug.message("Instantiated AuthContext with organization name: " 444 + orgName); 445 } 446 447 /** 448 * Method to reset this instance of <code>AuthContext</code> object, so 449 * that a new login process can be initiated. Authenticates the user to the 450 * same organization or resource this object was instantiated with. If this 451 * object was instantiated with a <code> 452 * Subject</code>, it will be 453 * ignored. 454 */ 455 protected void reset() throws LoginException { 456 authDebug.message("AuthContext::reset()"); 457 reset(null); 458 authDebug.message("AuthContext::reset() exiting"); 459 } 460 461 /** 462 * Method to reset this instance of <code>AuthContext</code> object, so 463 * that a new login process can be initiated for the given 464 * <code>Subject</code>. Authenticates the user to the same organization 465 * or resource this object was instantiated with. 466 */ 467 protected void reset(AuthSubject subject) throws LoginException { 468 469 if (authDebug.messageEnabled()) { 470 authDebug.message("AuthContext::reset(" + organizationName + ", " 471 + ((subject == null) ? "null" : subject.toString()) + ")"); 472 } 473 474 loginStatus = AUTH_NOT_STARTED; 475 informationRequired = null; 476 submittedInformation = null; 477 loginException = null; 478 loginThread = new AuthLoginThread(this); 479 authDebug.message("AuthLoginThread isAlive = " + loginThread.isAlive()); 480 481 String contextName = null; 482 483 if (applicationName == null) { 484 contextName = organizationName; 485 } else { 486 contextName = organizationName + "%" + applicationName; 487 } 488 489 authDebug 490 .message("AuthContext::reset:using contextName=" + contextName); 491 if (subject == null) { 492 loginContext = new LoginContext(contextName, loginThread); 493 } else { 494 loginContext = new LoginContext(contextName, subject, loginThread); 495 } 496 497 if (authDebug.messageEnabled()) { 498 authDebug 499 .message("Successfully reset AuthContext for organization: " 500 + organizationName 501 + ((subject == null) ? " with no subject name " 502 : " with subjects: " + subject)); 503 } 504 } 505 506 /** 507 * Returns the set of Principals the user has been authenticated as. This 508 * can be invoked only after successful authentication. If the 509 * authentication fails, this will return <code>null</code>. 510 */ 511 protected AuthSubject getSubject() { 512 authDebug.message("AuthContext::getSubject()"); 513 return (loginContext.getSubject()); 514 } 515 516 /** 517 * Method to start the login process. This method will 518 * read the plug-ins configured for the application and initialize them. 519 * 520 * @throws LoginException 521 * 522 * @supported.api 523 */ 524 public void startLogin() throws LoginException { 525 526 authDebug.message("AuthContext::startLogin() called"); 527 528 // Make sure we are the current state 529 if (getLoginStatus() != AUTH_NOT_STARTED) { 530 531 authDebug.message("AuthContext::startLogin called " 532 + "when the current login state is" + getLoginStatus()); 533 534 throw (new LoginException(myAuthI18n 535 .getString("authError-invalidMethod" + getLoginStatus()))); 536 } 537 538 // Change the login status 539 loginStatus = AUTH_IN_PROGRESS; 540 541 // Initiate the login 542 authDebug.message("AuthContext::startLogin() " 543 + "starting a new thread to run the login process"); 544 545 try { 546 loginThread.start(); 547 } catch (Exception ex) { 548 authDebug.message("exception starting thread: " + ex); 549 throw (new LoginException(ex.getMessage())); 550 } 551 } 552 553 /** 554 * Returns true if the login process requires more 555 * information from the user to complete the authentication. 556 * 557 * @return true if the login process requires more information from the user 558 * to complete the authentication. 559 * 560 * @supported.api 561 */ 562 public boolean hasMoreRequirements() { 563 authDebug.message("AuthContext::requiresMoreInformation()"); 564 565 if (getRequirements() == null) 566 return (false); 567 else 568 return (true); 569 } 570 571 /** 572 * Returns an array of <code>Callback</code> objects 573 * that must be populated by the user and returned back. These objects are 574 * requested by the authentication plug-ins, and these are usually displayed 575 * to the user. The user then provides the requested information for it to 576 * be authenticated. 577 * 578 * @return an array of <code>Callback</code> objects that must be 579 * populated by the user and returned back. 580 * 581 * @supported.api 582 */ 583 public Callback[] getRequirements() { 584 authDebug.message("AuthContext::getInformationRequired()"); 585 586 // Check the status of LOGIN 587 if (getLoginStatus() != AUTH_IN_PROGRESS) { 588 589 authDebug.message("AuthContext:getInformationRequired() " 590 + "called when the current login state is: " 591 + getLoginStatus()); 592 593 // Login has completed, could be either success or failure 594 return (null); 595 } 596 597 // Check if information required is present 598 while ((informationRequired == null) 599 && (getLoginStatus() == AUTH_IN_PROGRESS)) { 600 // wait for required information to be available 601 try { 602 authDebug.message("AuthContext::getInformationRequired" 603 + "() waiting for Callback array"); 604 605 synchronized (loginThread) { 606 if ((informationRequired == null) 607 && (getLoginStatus() == AUTH_IN_PROGRESS)) { 608 loginThread.wait(); 609 } 610 } 611 612 authDebug.message("AuthContext::getInformationRequired" 613 + "() returned from waiting for Callback array"); 614 615 } catch (InterruptedException ie) { 616 // do nothing 617 } 618 } 619 return (informationRequired); 620 } 621 622 /** 623 * Submits the populated <code>Callback</code> 624 * objects to the authentication plug-in modules. Called after 625 * <code>getInformationRequired</code> method and obtaining user's 626 * response to these requests. 627 * 628 * @param info 629 * array of <code>Callback</code> objects. 630 * 631 * @supported.api 632 */ 633 public void submitRequiredInformation(Callback[] info) { 634 authDebug.message("AuthContext::submitRequestedInformation()"); 635 636 informationRequired = null; 637 638 // Set the submitted info & wake up the callback hander thread 639 synchronized (loginThread) { 640 submittedInformation = info; 641 loginThread.notify(); 642 } 643 authDebug.message("AuthContext::submitRequestedInformation" 644 + "() sending notify to sleeping threads"); 645 } 646 647 /** 648 * Logs the user out. 649 * 650 * @throws LoginException 651 * 652 * @supported.api 653 */ 654 public void logout() throws LoginException { 655 authDebug.message("AuthContext::logout()"); 656 loginContext.logout(); 657 658 authDebug.message("Called LoginContext::logout()"); 659 loginStatus = AUTH_COMPLETED; 660 } 661 662 /** 663 * Returns login exception, if any, during the 664 * authentication process. Typically set when the login fails. 665 * 666 * @return login exception. 667 * 668 * @supported.api 669 */ 670 public LoginException getLoginException() { 671 authDebug.message("AuthContext::getLoginException()"); 672 return (loginException); 673 } 674 675 /** 676 * Returns the current state of the login process. 677 * Possible states are listed above. 678 * 679 * @return the current state of the login process. 680 * 681 * @supported.api 682 */ 683 public int getLoginStatus() { 684 authDebug.message("AuthContext::getLoginStatus()"); 685 return (loginStatus); 686 } 687 688 /** 689 * Method to set the login status. Used internally and not visible outside 690 * this package. 691 */ 692 protected void setLoginStatus(int status) { 693 authDebug.message("AuthContext::setLoginStatus()"); 694 loginStatus = status; 695 } 696 697 /** 698 * Returns the (first) <code>AuthPrincipal</code> in 699 * the <code>Subject</code>. Returns the first <code>Principal</code>, 700 * if more than one exists. 701 * 702 * @return the (first) <code>AuthPrincipal</code> in the 703 * <code>Subject</code>. 704 * 705 * @supported.api 706 */ 707 public Principal getPrincipal() { 708 Set sop = getSubject().getPrincipals(); 709 if (authDebug.messageEnabled()) { 710 authDebug.message("AuthContext::getAuthPrincipal(): " + sop); 711 } 712 Iterator items = sop.iterator(); 713 if (items.hasNext()) { 714 return ((Principal) items.next()); 715 } else { 716 return null; 717 } 718 } 719 720 /** 721 * Method to get the (first) <code>AuthPrincipal</code> in the 722 * <code>Subject</code>. Returns the first <code>Principal</code>, if 723 * more than one exists. 724 * 725 * @deprecated Use getPrincipal() instead 726 */ 727 public AuthPrincipal getAuthPrincipal() { 728 authDebug.message("AuthContext::getAuthPrincipal()"); 729 730 Set sop = getSubject().getPrincipals(); 731 Iterator items = sop.iterator(); 732 if (items.hasNext()) 733 return ((AuthPrincipal) items.next()); 734 else 735 return null; 736 } 737 738 /** 739 * Method to get the set of <code>AuthPrincipal</code>s in the 740 * <code>Subject</code>. 741 */ 742 protected Set getPrincipals() { 743 authDebug.message("AuthContext::getAuthPrincipals()"); 744 return (getSubject().getPrincipals()); 745 } 746 747 /** 748 * Method to get organization name that was set during 749 * construction of this instance. 750 * 751 * @return organization name; <code>null</code> if it was not initialized 752 * during construction of this instance 753 * 754 * @supported.api 755 */ 756 public String getOrganizationName() { 757 if (organizationName == null) { 758 try { 759 organizationName = DN.valueOf(ServiceManager.getBaseDN()).toString().toLowerCase(); 760 } catch (LocalizedIllegalArgumentException e) { 761 throw new IllegalStateException("AuthContext.getOrganizationName: Base DN cannot be parsed", e); 762 } 763 } 764 return organizationName; 765 } 766 767 protected String getApplicationName() { 768 return applicationName; 769 } 770 771 /** 772 * Method to get the Single-Sign-On (SSO) Token. This 773 * token can be used as the authenticated token. 774 * 775 * @return single-sign-on token. 776 * @throws InvalidAuthContextException 777 * 778 * @supported.api 779 */ 780 public SSOToken getSSOToken() throws InvalidAuthContextException { 781 if (token != null) { 782 return (token); 783 } 784 785 token = new AuthSSOToken(this); 786 try { 787 // Set Organization 788 if (getOrganizationName() != null) { 789 token.setProperty(Constants.ORGANIZATION, 790 getOrganizationName()); 791 } 792 793 // Set Host name 794 InetAddress address = InetAddress.getLocalHost(); 795 String ipAddress = address.getHostAddress(); 796 797 798 if (authDebug.messageEnabled()) { 799 authDebug.message("Complete Host : " + address.toString()); 800 authDebug.message("getSSOToken : IP : " + ipAddress); 801 } 802 803 if (ipAddress != null) { 804 if (isEnableHostLookUp) { 805 final String strHostName = address.getHostName(); 806 if (authDebug.messageEnabled()) { 807 authDebug.message("getSSOToken : HOST Name : " + strHostName); 808 } 809 if (strHostName != null) { 810 token.setProperty("HostName", strHostName); 811 } 812 } else { 813 token.setProperty("HostName", ipAddress); 814 } 815 token.setProperty("Host", ipAddress); 816 } 817 818 // Set AuthType 819 token.setProperty("AuthType", "ldap"); 820 821 // Set Principal 822 String principal = getPrincipal().getName(); 823 if (principal != null) { 824 token.setProperty("Principal", principal); 825 // Set Universal Identifier 826 String username = principal; 827 if (isDN(principal)) { 828 // Get the username 829 username = rdnValueFromDn(principal); 830 } 831 // Since internal auth will be used during install time 832 // and during boot strap for users "dsame" and "amadmin" 833 // the IdType will be hardcoded to User 834 StringBuilder uuid = new StringBuilder(100); 835 uuid.append("id=").append(username) 836 .append(",ou=user,").append(getOrganizationName()); 837 token.setProperty(Constants.UNIVERSAL_IDENTIFIER, 838 uuid.toString()); 839 } 840 841 // Set AuthLevel 842 token.setProperty("AuthLevel", Integer.toString(0)); 843 844 //Set ContextId 845 SecureRandom secureRandom = 846 SecureRandomManager.getSecureRandom(); 847 String amCtxId = 848 Long.toHexString(secureRandom.nextLong()); 849 token.setProperty(Constants.AM_CTX_ID, amCtxId); 850 851 if (authDebug.messageEnabled()) { 852 authDebug.message("SSOToken : Organization : " 853 + token.getProperty("Organization")); 854 authDebug.message("SSOToken : Principal : " 855 + token.getProperty("Principal")); 856 authDebug.message("SSOToken : HostName : " 857 + token.getProperty("HostName")); 858 authDebug.message("SSOToken : Host : " 859 + token.getProperty("Host")); 860 authDebug.message("SSOToken : getIPAddress : " 861 + token.getIPAddress()); 862 authDebug.message("SSOToken : getHostName : " 863 + token.getHostName()); 864 authDebug.message("SSOToken : ContextId : " 865 + token.getProperty(Constants.AM_CTX_ID)); 866 } 867 868 } catch (Exception e) { 869 if (authDebug.warningEnabled()) { 870 authDebug.warning("getSSOToken: setProperty exception : ", e); 871 } 872 } 873 874 return (token); 875 } 876}