SSOProviderImpl.java revision 26304a2a091af368cfc16c977bcce6d17195360a
0N/A/**
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0N/A *
0N/A * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
0N/A *
0N/A * The contents of this file are subject to the terms
0N/A * of the Common Development and Distribution License
0N/A * (the License). You may not use this file except in
0N/A * compliance with the License.
0N/A *
0N/A * You can obtain a copy of the License at
0N/A * https://opensso.dev.java.net/public/CDDLv1.0.html or
0N/A * opensso/legal/CDDLv1.0.txt
0N/A * See the License for the specific language governing
0N/A * permission and limitations under the License.
0N/A *
0N/A * When distributing Covered Code, include this CDDL
0N/A * Header Notice in each file and include the License file
873N/A * at opensso/legal/CDDLv1.0.txt.
0N/A * If applicable, add the following below the CDDL Header,
0N/A * with the fields enclosed by brackets [] replaced by
0N/A * your own identifying information:
0N/A * "Portions Copyrighted [year] [name of copyright owner]"
0N/A *
3231N/A * $Id: SSOProviderImpl.java,v 1.9 2009/02/19 05:04:01 bhavnab Exp $
6197N/A *
0N/A */
0N/A
0N/A/**
0N/A * Portions copyright 2013-2016 ForgeRock AS.
0N/A */
0N/Apackage com.iplanet.sso.providers.dpro;
0N/A
0N/Aimport java.net.InetAddress;
6197N/Aimport java.util.HashSet;
0N/Aimport java.util.Set;
0N/A
1689N/Aimport javax.servlet.http.HttpServletRequest;
0N/A
0N/Aimport org.forgerock.openam.session.SessionCache;
0N/Aimport org.forgerock.openam.utils.ClientUtils;
0N/Aimport org.forgerock.util.annotations.VisibleForTesting;
988N/A
1177N/Aimport com.iplanet.am.util.SystemProperties;
0N/Aimport com.iplanet.dpro.session.Session;
0N/Aimport com.iplanet.dpro.session.SessionException;
0N/Aimport com.iplanet.dpro.session.SessionID;
0N/Aimport com.iplanet.sso.SSOException;
0N/Aimport com.iplanet.sso.SSOProvider;
0N/Aimport com.iplanet.sso.SSOToken;
0N/Aimport com.iplanet.sso.SSOTokenID;
0N/Aimport com.sun.identity.common.SearchResults;
0N/Aimport com.sun.identity.shared.debug.Debug;
0N/A
0N/A/**
0N/A * This <code>final</code> class <code>SSOProviderImpl</code> implements
0N/A * <code>SSOProvider</code> interface and provides implementation of the methods
0N/A * to create , destroy , check the validity of a single sign on token.
2095N/A *
2095N/A * @supported.api
2095N/A *
2095N/A * Note: Used by ClientSDK, therefore must not use Guice for initialisation.
2095N/A */
2095N/Apublic final class SSOProviderImpl implements SSOProvider {
1689N/A
0N/A /**
6197N/A * Debug SSOProvider
0N/A */
0N/A public static Debug debug = null;
6197N/A
0N/A /**
0N/A * Check to see if the clientIPCheck is enabled
6197N/A */
0N/A private static boolean checkIP = Boolean.valueOf(
0N/A SystemProperties.get("com.iplanet.am.clientIPCheckEnabled"))
0N/A .booleanValue();
0N/A
0N/A private final SessionCache sessionCache;
0N/A
0N/A // Initialize debug instance;
0N/A static {
0N/A debug = Debug.getInstance("amSSOProvider");
0N/A }
0N/A
0N/A /**
0N/A * Constructs a instance of <code>SSOProviderImpl</code>
0N/A *
0N/A * @throws SSOException
0N/A * @supported.api
0N/A */
0N/A public SSOProviderImpl() throws SSOException {
0N/A this(SessionCache.getInstance());
0N/A }
0N/A
0N/A @VisibleForTesting
0N/A SSOProviderImpl(SessionCache sessionCache) {
0N/A this.sessionCache = sessionCache;
0N/A }
0N/A
0N/A /**
0N/A * Creates a single sign on token for the <code>HttpRequest</code>
0N/A *
0N/A * @param request <code>HttpServletRequest</code>
0N/A * @return single sign on token for the request
0N/A * @throws SSOException if the single sign on token cannot be created.
0N/A */
0N/A public SSOToken createSSOToken(HttpServletRequest request)
0N/A throws SSOException {
0N/A try {
0N/A SessionID sid = new SessionID(request);
0N/A Session session = sessionCache.getSession(sid);
0N/A if (sid != null) {
0N/A Boolean cookieMode = sid.getCookieMode();
0N/A if (debug.messageEnabled()) {
0N/A debug.message("cookieMode is :" + cookieMode);
0N/A }
6197N/A if (cookieMode != null) {
0N/A session.setCookieMode(cookieMode);
0N/A }
0N/A }
0N/A if (checkIP && !isIPValid(session, ClientUtils.getClientIPAddress(request))) {
0N/A throw new Exception(SSOProviderBundle.getString("invalidIP"));
0N/A }
0N/A SSOToken ssoToken = new SSOTokenImpl(session);
0N/A return ssoToken;
0N/A } catch (Exception e) {
0N/A if (debug.messageEnabled()) {
0N/A debug.message("could not create SSOToken from HttpRequest ("
0N/A + e.getMessage()
0N/A + ")");
0N/A }
0N/A throw new SSOException(e);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates a single sign on token with user or service as the entity
0N/A *
0N/A * @param user Principal representing a user or service
0N/A * @param password password string.
0N/A * @return single sign on token
0N/A * @throws SSOException if the single sign on token cannot be created.
0N/A * @throws UnsupportedOperationException Thrown to indicate that the
0N/A * requested operation is not supported.
0N/A * @deprecated This method has been deprecated. Please use the
0N/A * regular LDAP authentication mechanism instead. More information
0N/A * on how to use the authentication programming interfaces as well as the
0N/A * code samples can be obtained from the "Authenticating Using
0N/A * OpenAM Java SDK" chapter of the OpenAM Developer's Guide.
0N/A */
0N/A public SSOToken createSSOToken(java.security.Principal user, String password)
0N/A throws SSOException, UnsupportedOperationException {
0N/A try {
0N/A SSOTokenImpl ssoToken = new SSOTokenImpl(user, password);
0N/A if (debug.messageEnabled()) {
0N/A debug.message("SSO token ldap auth successful for "
0N/A + user.toString());
0N/A }
0N/A return ssoToken;
0N/A } catch (Exception e) {
0N/A if (debug.messageEnabled()) {
0N/A debug.message("could not create SSOToken for user \""
0N/A + user.getName()
0N/A + "\"", e);
0N/A }
0N/A throw new SSOException(e);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates a single sign on token. Note: this method should remain private
0N/A * and get called only by the AuthContext API. Note also: this method may reset
0N/A * the idle time of the session.
0N/A *
0N/A * @param tokenId single sign on token ID.
0N/A * @param invokedByAuth boolean flag indicating that this method has
0N/A * been invoked by the AuthContext.getSSOToken() API.
0N/A * @return single sign on token.
0N/A * @throws SSOException if the single sign on token cannot be created.
0N/A * @throws UnsupportedOperationException Thrown to indicate that the
0N/A * requested operation is not supported.
0N/A */
0N/A public SSOToken createSSOToken(String tokenId, boolean invokedByAuth)
0N/A throws SSOException, UnsupportedOperationException {
0N/A return createSSOToken(tokenId, invokedByAuth, true);
0N/A }
0N/A
0N/A /**
0N/A * Creates a single sign on token.
0N/A *
0N/A * @param tokenId single sign on token ID.
0N/A * @param invokedByAuth boolean flag indicating that this method has been invoked by the AuthContext.getSSOToken()
0N/A * API.
0N/A * @param possiblyResetIdleTime If true, the idle time of the token/session may be reset to zero. If false, the
0N/A * idle time will never be reset.
0N/A * @return single sign on token.
0N/A * @throws SSOException if the single sign on token cannot be created for any reason.
0N/A * @throws java.lang.UnsupportedOperationException only here to satisfy the interface, this is never thrown.
0N/A */
0N/A public SSOToken createSSOToken(String tokenId, boolean invokedByAuth, boolean possiblyResetIdleTime)
0N/A throws SSOException, UnsupportedOperationException {
0N/A
0N/A try {
0N/A SessionID sessionId = new SessionID(tokenId);
0N/A sessionId.setComingFromAuth(invokedByAuth);
0N/A Session session = sessionCache.getSession(sessionId, false, possiblyResetIdleTime);
0N/A SSOToken ssoToken = new SSOTokenImpl(session);
0N/A return ssoToken;
0N/A } catch (Exception e) {
0N/A if (debug.messageEnabled()) {
0N/A debug.message("SSOProviderImpl.createSSOToken(tokenId, "
0N/A + invokedByAuth
0N/A + ", "
0N/A + possiblyResetIdleTime
0N/A + ") could not create SSOToken for token ID \""
0N/A + tokenId
0N/A + "\" ("
0N/A + e.getMessage()
0N/A + ")");
0N/A }
0N/A throw new SSOException(e);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates a single sign on token.
0N/A *
0N/A * @param tokenId single sign on token ID.
0N/A * @return single sign on token.
0N/A * @throws SSOException if the single sign on token cannot be created.
0N/A * @throws UnsupportedOperationException
988N/A * @deprecated Use #createSSOToken(String, String)
988N/A */
988N/A public SSOToken createSSOToken(String tokenId)
988N/A throws SSOException,
0N/A UnsupportedOperationException {
2095N/A return createSSOToken(tokenId, false);
2095N/A }
2095N/A
2095N/A /**
2095N/A * Creates a single sign on token.
0N/A *
988N/A * @param tokenId single sign on token ID.
0N/A * @param clientIP client IP address
0N/A * @return single sign on token.
0N/A * @throws SSOException if the single sign on token cannot be created.
0N/A * @throws UnsupportedOperationException Thrown to indicate that the
0N/A * requested operation is not supported.
0N/A * @deprecated Use #createSSOToken(String, String)
0N/A */
0N/A public SSOToken createSSOToken(String tokenId, String clientIP)
0N/A throws SSOException, UnsupportedOperationException {
0N/A try {
0N/A SessionID sessionId = new SessionID(tokenId);
0N/A Session session = sessionCache.getSession(sessionId);
0N/A if (checkIP && !isIPValid(session, clientIP)) {
0N/A throw new Exception(SSOProviderBundle.getString("invalidIP"));
0N/A }
0N/A SSOToken ssoToken = new SSOTokenImpl(session);
0N/A return ssoToken;
0N/A } catch (Exception e) {
0N/A if (debug.messageEnabled()) {
0N/A debug.message("could not create SSOToken for token ID \""
0N/A + tokenId
0N/A + "\" ("
0N/A + e.getMessage()
0N/A + ")");
0N/A }
0N/A throw new SSOException(e);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Checks the validity of the single sign on token
0N/A *
0N/A * @param token The single sign on token object to be validated
0N/A * @return Returns true if the <code>SSOToken</code> is valid
0N/A */
988N/A @Override
988N/A public boolean isValidToken(SSOToken token) {
988N/A return isValidToken(token, true);
988N/A }
0N/A
2095N/A /**
2095N/A * Checks the validity of the single sign on token
2095N/A *
2095N/A * @param token The single sign on token object to be validated
2095N/A * @param refresh Flag indicating whether refreshing the token is allowed
0N/A * @return Returns true if the <code>SSOToken</code> is valid, false otherwise
0N/A */
988N/A @Override
0N/A public boolean isValidToken(SSOToken token, boolean refresh) {
0N/A /*
0N/A * If the token was created from createSSOToken(Principal, password)
0N/A * there is no association with session. Use this temp solution for now.
0N/A * If this method is going to go away, we can remove that method, otherwise
0N/A * a better mechanism has to be implemented.
0N/A */
0N/A SSOTokenImpl tokenImpl = (SSOTokenImpl) token;
0N/A return (tokenImpl.isValid(refresh));
0N/A }
0N/A
1689N/A /**
2095N/A * Checks if the single sign on token is valid.
2095N/A *
1689N/A * @param token single sign on token.
2095N/A * @throws SSOException if the single sign on token is not valid.
2095N/A */
2095N/A public void validateToken(SSOToken token) throws SSOException {
2095N/A try {
2095N/A /*
2095N/A * if the token was created from createSSOToken(Principal, password)
2095N/A * there is no association with session. Use this temp solution now.
2095N/A * if this method is going to go away, we can remove that method.
1689N/A * otherwise a better mechanism has to be implemented.
2095N/A */
2095N/A SSOTokenImpl tokenImpl = (SSOTokenImpl) token;
2095N/A tokenImpl.validate();
2095N/A } catch (Exception e) {
2095N/A if (debug.messageEnabled()) {
2095N/A debug.message("validateToken: ", e);
1689N/A }
2095N/A throw new SSOException(SSOProviderBundle.rbName, "invalidtoken", null);
2095N/A }
1689N/A }
1689N/A
1689N/A /**
2095N/A * Destroys a single sign on token
2095N/A *
1689N/A * @param token The single sign on token object to be destroyed
2095N/A * @throws SSOException if the given token cannot be destroyed
2095N/A */
2095N/A public void destroyToken(SSOToken token) throws SSOException {
2095N/A try {
2095N/A SSOTokenImpl tokenImpl = (SSOTokenImpl) token;
2095N/A if (tokenImpl.isLdapConnection() == true) {
2095N/A tokenImpl.setStatus(false);
2095N/A return;
2095N/A }
2095N/A SSOTokenID tokenid = token.getTokenID();
2095N/A String id = tokenid.toString();
2095N/A SessionID sessid = new SessionID(id);
2095N/A Session session = sessionCache.getSession(sessid);
1689N/A session.destroySession(session);
2095N/A } catch (Exception e) {
2095N/A if (debug.messageEnabled()) {
2095N/A debug.message("DestroyToken: ", e);
2095N/A }
2095N/A throw new SSOException(e);
2095N/A }
2095N/A }
2095N/A
2095N/A @Override
1689N/A public void logout(final SSOToken token) throws SSOException {
1689N/A try {
1689N/A Session session = sessionCache.getSession(new SessionID(token.getTokenID().toString()));
1689N/A session.logout();
0N/A } catch (SessionException e) {
0N/A if (debug.messageEnabled()) {
debug.message("Logout: ", e);
}
throw new SSOException(e);
}
}
/**
* Validate the IP address of the client with the IP stored in Session.
*
* @param sess Session object associated with the token
* @param clientIP IP address of the current client who made
* <code>HttpRequest</code>.
* @return Returns true if the IP is valid else false.
* @throws SSOException if IP cannot be validated for the given session
*/
public boolean isIPValid(Session sess, String clientIP) throws SSOException {
boolean check = false;
try {
InetAddress sessIPAddress = InetAddress.getByName(sess
.getProperty("Host"));
InetAddress clientIPAddress = InetAddress.getByName(clientIP);
if (sessIPAddress.equals(clientIPAddress)) {
check = true;
}
} catch (Exception e) {
if (debug.messageEnabled()) {
debug.message("IP address check of Token Failed", e);
}
}
return check;
}
/**
* Refresh the Session corresponding to the single sign on token from the
* Session Server.
*
* @param token single sign on token for which session need to be refreshed
* @throws SSOException if the session cannot be refreshed
*/
@Override
public void refreshSession(SSOToken token) throws SSOException {
refreshSession(token, true);
}
/**
* Refresh the Session corresponding to the single sign on token from the
* Session Server.
*
* @param token single sign on token for which session need to be refreshed.
* @param possiblyResetIdleTime if true, the idle time may be reset, if false it will never be.
* @throws SSOException if the session cannot be refreshed.
*/
@Override
public void refreshSession(SSOToken token, boolean possiblyResetIdleTime) throws SSOException {
try {
SSOTokenID tokenId = token.getTokenID();
SessionID sid = new SessionID(tokenId.toString());
Session session = sessionCache.getSession(sid);
session.refresh(possiblyResetIdleTime);
} catch (Exception e) {
debug.error("Error in refreshing the session from sessions server");
throw new SSOException(e);
}
}
/**
* Destroys a single sign on token.
*
* @param destroyer
* The single sign on token object used to authorize the
* operation
* @param destroyed
* The single sign on token object to be destroyed.
* @throws SSOException
* if the there was an error during communication with session
* service.
*
* @supported.api
*/
public void destroyToken(SSOToken destroyer, SSOToken destroyed)
throws SSOException {
try {
Session requester = ((SSOTokenImpl) destroyer).getSession();
Session target = ((SSOTokenImpl) destroyed).getSession();
requester.destroySession(target);
} catch (SessionException e) {
throw new SSOException(e);
}
}
/**
* Returns a list of single sign on token objects
* which correspond to valid Sessions accessible to requester. single sign
* on token objects returned are restricted: they can only be used to
* retrieve properties and destroy sessions they represent.
*
* @param requester
* The single sign on token object used to authorize the
* operation
* @param server
* The server for which the valid sessions are to be retrieved
* @return Set of Valid Sessions
* @throws SSOException
* if the there was an error during communication with session
* service.
*
* @supported.api
*/
public Set<SSOToken> getValidSessions(SSOToken requester, String server)
throws SSOException {
Set<SSOToken> results = new HashSet<>();
try {
SearchResults<Session> result = ((SSOTokenImpl) requester).getSession().getValidSessions(server, null);
for (Session s : result.getSearchResults()) {
if (s != null) {
results.add(new SSOTokenImpl(s));
}
}
} catch (SessionException e) {
throw new SSOException(e);
}
return results;
}
}