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: SSOProviderImpl.java,v 1.9 2009/02/19 05:04:01 bhavnab Exp $ 026 * 027 */ 028 029/** 030 * Portions copyright 2013-2014 ForgeRock AS. 031 */ 032package com.iplanet.sso.providers.dpro; 033 034import com.iplanet.am.util.SystemProperties; 035import com.iplanet.dpro.session.Session; 036import com.iplanet.dpro.session.SessionException; 037import com.iplanet.dpro.session.SessionID; 038import com.iplanet.sso.SSOException; 039import com.iplanet.sso.SSOProvider; 040import com.iplanet.sso.SSOToken; 041import com.iplanet.sso.SSOTokenID; 042import com.sun.identity.common.SearchResults; 043import com.sun.identity.shared.debug.Debug; 044import org.forgerock.openam.utils.ClientUtils; 045import java.net.InetAddress; 046import java.util.HashSet; 047import java.util.Iterator; 048import java.util.Set; 049import javax.servlet.http.HttpServletRequest; 050 051/** 052 * This <code>final</code> class <code>SSOProviderImpl</code> implements 053 * <code>SSOProvider</code> interface and provides implementation of the methods 054 * to create , destroy , check the validity of a single sign on token. 055 * 056 * @supported.api 057 */ 058public final class SSOProviderImpl implements SSOProvider { 059 060 /** 061 * Debug SSOProvider 062 */ 063 public static Debug debug = null; 064 065 /** 066 * Check to see if the clientIPCheck is enabled 067 */ 068 private static boolean checkIP = Boolean.valueOf( 069 SystemProperties.get("com.iplanet.am.clientIPCheckEnabled")) 070 .booleanValue(); 071 072 // Initialize debug instance; 073 static { 074 debug = Debug.getInstance("amSSOProvider"); 075 } 076 077 /** 078 * Constructs a instance of <code>SSOProviderImpl</code> 079 * 080 * @throws SSOException 081 * @supported.api 082 */ 083 public SSOProviderImpl() throws SSOException { 084 } 085 086 /** 087 * Creates a single sign on token for the <code>HttpRequest</code> 088 * 089 * @param request <code>HttpServletRequest</code> 090 * @return single sign on token for the request 091 * @throws SSOException if the single sign on token cannot be created. 092 */ 093 public SSOToken createSSOToken(HttpServletRequest request) 094 throws SSOException { 095 try { 096 SessionID sid = new SessionID(request); 097 Session session = Session.getSession(sid); 098 if (sid != null) { 099 Boolean cookieMode = sid.getCookieMode(); 100 if (debug.messageEnabled()) { 101 debug.message("cookieMode is :" + cookieMode); 102 } 103 if (cookieMode != null) { 104 session.setCookieMode(cookieMode); 105 } 106 } 107 if (checkIP && !isIPValid(session, ClientUtils.getClientIPAddress(request))) { 108 throw new Exception(SSOProviderBundle.getString("invalidIP")); 109 } 110 SSOToken ssoToken = new SSOTokenImpl(session); 111 return ssoToken; 112 } catch (Exception e) { 113 if (debug.messageEnabled()) { 114 debug.message("could not create SSOToken from HttpRequest", e); 115 } 116 throw new SSOException(e); 117 } 118 } 119 120 /** 121 * Creates a single sign on token with user or service as the entity 122 * 123 * @param user Principal representing a user or service 124 * @param password password string. 125 * @return single sign on token 126 * @throws SSOException if the single sign on token cannot be created. 127 * @throws UnsupportedOperationException Thrown to indicate that the 128 * requested operation is not supported. 129 * @deprecated This method has been deprecated. Please use the 130 * regular LDAP authentication mechanism instead. More information 131 * on how to use the authentication programming interfaces as well as the 132 * code samples can be obtained from the "Authentication 133 * Service" chapter of the OpenSSO Developer's Guide. 134 */ 135 public SSOToken createSSOToken(java.security.Principal user, 136 String password) throws SSOException, UnsupportedOperationException { 137 try { 138 SSOTokenImpl ssoToken = new SSOTokenImpl(user, password); 139 if (debug.messageEnabled()) { 140 debug.message("SSO token ldap auth successful for " 141 + user.toString()); 142 } 143 return ssoToken; 144 } catch (Exception e) { 145 if (debug.messageEnabled()) { 146 debug.message("could not create SSOToken for user \"" 147 + user.getName() 148 + "\"", e); 149 } 150 throw new SSOException(e); 151 } 152 } 153 154 /** 155 * Creates a single sign on token. Note: this method should remain private 156 * and get called only by the AuthContext API. Note also: this method may reset 157 * the idle time of the session. 158 * 159 * @param tokenId single sign on token ID. 160 * @param invokedByAuth boolean flag indicating that this method has 161 * been invoked by the AuthContext.getSSOToken() API. 162 * @return single sign on token. 163 * @throws SSOException if the single sign on token cannot be created. 164 * @throws UnsupportedOperationException Thrown to indicate that the 165 * requested operation is not supported. 166 */ 167 public SSOToken createSSOToken(String tokenId, boolean invokedByAuth) 168 throws SSOException, UnsupportedOperationException { 169 return createSSOToken(tokenId, invokedByAuth, true); 170 } 171 172 /** 173 * Creates a single sign on token. 174 * 175 * @param tokenId single sign on token ID. 176 * @param invokedByAuth boolean flag indicating that this method has been invoked by the AuthContext.getSSOToken() 177 * API. 178 * @param possiblyResetIdleTime If true, the idle time of the token/session may be reset to zero. If false, the 179 * idle time will never be reset. 180 * @return single sign on token. 181 * @throws SSOException if the single sign on token cannot be created for any reason. 182 * @throws java.lang.UnsupportedOperationException only here to satisfy the interface, this is never thrown. 183 */ 184 public SSOToken createSSOToken(String tokenId, boolean invokedByAuth, boolean possiblyResetIdleTime) 185 throws SSOException, UnsupportedOperationException { 186 187 try { 188 SessionID sessionId = new SessionID(tokenId); 189 sessionId.setComingFromAuth(invokedByAuth); 190 Session session = Session.getSession(sessionId, false, possiblyResetIdleTime); 191 SSOToken ssoToken = new SSOTokenImpl(session); 192 return ssoToken; 193 } catch (Exception e) { 194 if (debug.messageEnabled()) { 195 debug.message("SSOProviderImpl.createSSOToken(tokenId, " 196 + invokedByAuth 197 + ", " 198 + possiblyResetIdleTime 199 + ") could not create SSOToken for token ID \"" 200 + tokenId 201 + "\"", e); 202 } 203 throw new SSOException(e); 204 } 205 } 206 207 /** 208 * Creates a single sign on token. 209 * 210 * @param tokenId single sign on token ID. 211 * @return single sign on token. 212 * @throws SSOException if the single sign on token cannot be created. 213 * @throws UnsupportedOperationException 214 * @deprecated Use #createSSOToken(String, String) 215 */ 216 public SSOToken createSSOToken(String tokenId) 217 throws SSOException, 218 UnsupportedOperationException { 219 return createSSOToken(tokenId, false); 220 } 221 222 /** 223 * Creates a single sign on token. 224 * 225 * @param tokenId single sign on token ID. 226 * @param clientIP client IP address 227 * @return single sign on token. 228 * @throws SSOException if the single sign on token cannot be created. 229 * @throws UnsupportedOperationException Thrown to indicate that the 230 * requested operation is not supported. 231 * @deprecated Use #createSSOToken(String, String) 232 */ 233 public SSOToken createSSOToken(String tokenId, String clientIP) 234 throws SSOException, UnsupportedOperationException { 235 try { 236 SessionID sessionId = new SessionID(tokenId); 237 Session session = Session.getSession(sessionId); 238 if (checkIP && !isIPValid(session, clientIP)) { 239 throw new Exception(SSOProviderBundle.getString("invalidIP")); 240 } 241 SSOToken ssoToken = new SSOTokenImpl(session); 242 return ssoToken; 243 } catch (Exception e) { 244 if (debug.messageEnabled()) { 245 debug.message("could not create SSOToken for token ID \"" 246 + tokenId 247 + "\"", e); 248 } 249 throw new SSOException(e); 250 } 251 } 252 253 /** 254 * Checks the validity of the single sign on token 255 * 256 * @param token The single sign on token object to be validated 257 * @return Returns true if the <code>SSOToken</code> is valid 258 */ 259 @Override 260 public boolean isValidToken(SSOToken token) { 261 return isValidToken(token, true); 262 } 263 264 /** 265 * Checks the validity of the single sign on token 266 * 267 * @param token The single sign on token object to be validated 268 * @param refresh Flag indicating whether refreshing the token is allowed 269 * @return Returns true if the <code>SSOToken</code> is valid, false otherwise 270 */ 271 @Override 272 public boolean isValidToken(SSOToken token, boolean refresh) { 273 /* 274 * If the token was created from createSSOToken(Principal, password) 275 * there is no association with session. Use this temp solution for now. 276 * If this method is going to go away, we can remove that method, otherwise 277 * a better mechanism has to be implemented. 278 */ 279 SSOTokenImpl tokenImpl = (SSOTokenImpl) token; 280 return (tokenImpl.isValid(refresh)); 281 } 282 283 /** 284 * Checks if the single sign on token is valid. 285 * 286 * @param token single sign on token. 287 * @throws SSOException if the single sign on token is not valid. 288 */ 289 public void validateToken(SSOToken token) throws SSOException { 290 try { 291 /* 292 * if the token was created from createSSOToken(Principal, password) 293 * there is no association with session. Use this temp solution now. 294 * if this method is going to go away, we can remove that method. 295 * otheriwse a better mechanism has to be implemented. 296 */ 297 SSOTokenImpl tokenImpl = (SSOTokenImpl) token; 298 tokenImpl.validate(); 299 } catch (Exception e) { 300 if (debug.messageEnabled()) { 301 debug.message("validateToken: ", e); 302 } 303 throw new SSOException(SSOProviderBundle.rbName, "invalidtoken", 304 null); 305 } 306 } 307 308 /** 309 * Destroys a single sign on token 310 * 311 * @param token The single sign on token object to be destroyed 312 * @throws SSOException if the given token cannot be destroyed 313 */ 314 public void destroyToken(SSOToken token) throws SSOException { 315 try { 316 SSOTokenImpl tokenImpl = (SSOTokenImpl) token; 317 if (tokenImpl.isLdapConnection() == true) { 318 tokenImpl.setStatus(false); 319 return; 320 } 321 SSOTokenID tokenid = token.getTokenID(); 322 String id = tokenid.toString(); 323 SessionID sessid = new SessionID(id); 324 Session session = Session.getSession(sessid); 325 session.destroySession(session); 326 } catch (Exception e) { 327 if (debug.messageEnabled()) { 328 debug.message("DestroyToken: ", e); 329 } 330 throw new SSOException(e); 331 } 332 } 333 334 /** 335 * Validate the IP address of the client with the IP stored in Session. 336 * 337 * @param sess Session object associated with the token 338 * @param clientIP IP address of the current client who made 339 * <code>HttpRequest</code>. 340 * @return Returns true if the IP is valid else false. 341 * @throws SSOException if IP cannot be validated for the given session 342 */ 343 public boolean isIPValid(Session sess, String clientIP) throws SSOException { 344 boolean check = false; 345 try { 346 InetAddress sessIPAddress = InetAddress.getByName(sess 347 .getProperty("Host")); 348 InetAddress clientIPAddress = InetAddress.getByName(clientIP); 349 if (sessIPAddress.equals(clientIPAddress)) { 350 check = true; 351 } 352 } catch (Exception e) { 353 if (debug.messageEnabled()) { 354 debug.message("IP address check of Token Failed", e); 355 } 356 } 357 return check; 358 } 359 360 /** 361 * Refresh the Session corresponding to the single sign on token from the 362 * Session Server. 363 * 364 * @param token single sign on token for which session need to be refreshed 365 * @throws SSOException if the session cannot be refreshed 366 */ 367 @Override 368 public void refreshSession(SSOToken token) throws SSOException { 369 refreshSession(token, true); 370 } 371 372 /** 373 * Refresh the Session corresponding to the single sign on token from the 374 * Session Server. 375 * 376 * @param token single sign on token for which session need to be refreshed. 377 * @param possiblyResetIdleTime if true, the idle time may be reset, if false it will never be. 378 * @throws SSOException if the session cannot be refreshed. 379 */ 380 @Override 381 public void refreshSession(SSOToken token, boolean possiblyResetIdleTime) throws SSOException { 382 try { 383 SSOTokenID tokenId = token.getTokenID(); 384 SessionID sid = new SessionID(tokenId.toString()); 385 Session session = Session.getSession(sid); 386 session.refresh(possiblyResetIdleTime); 387 } catch (Exception e) { 388 debug.error("Error in refreshing the session from sessions server"); 389 throw new SSOException(e); 390 } 391 } 392 393 /** 394 * Destroys a single sign on token. 395 * 396 * @param destroyer 397 * The single sign on token object used to authorize the 398 * operation 399 * @param destroyed 400 * The single sign on token object to be destroyed. 401 * @throws SSOException 402 * if the there was an error during communication with session 403 * service. 404 * 405 * @supported.api 406 */ 407 public void destroyToken(SSOToken destroyer, SSOToken destroyed) 408 throws SSOException { 409 try { 410 Session requester = ((SSOTokenImpl) destroyer).getSession(); 411 Session target = ((SSOTokenImpl) destroyed).getSession(); 412 requester.destroySession(target); 413 } catch (SessionException e) { 414 throw new SSOException(e); 415 } 416 } 417 418 /** 419 * Returns a list of single sign on token objects 420 * which correspond to valid Sessions accessible to requester. single sign 421 * on token objects returned are restricted: they can only be used to 422 * retrieve properties and destroy sessions they represent. 423 * 424 * @param requester 425 * The single sign on token object used to authorize the 426 * operation 427 * @param server 428 * The server for which the valid sessions are to be retrieved 429 * @return Set of Valid Sessions 430 * @throws SSOException 431 * if the there was an error during communication with session 432 * service. 433 * 434 * @supported.api 435 */ 436 public Set getValidSessions(SSOToken requester, String server) 437 throws SSOException { 438 Set results = new HashSet(); 439 try { 440 441 SearchResults result = ((SSOTokenImpl) requester).getSession() 442 .getValidSessions(server, null); 443 444 for (Iterator iter = result.getResultAttributes().values() 445 .iterator(); iter.hasNext();) { 446 Session s = (Session) iter.next(); 447 if (s != null) { 448 results.add(new SSOTokenImpl(s)); 449 } 450 } 451 } catch (SessionException e) { 452 throw new SSOException(e); 453 } 454 return results; 455 } 456}
Copyright © 2010-2017, ForgeRock All Rights Reserved.