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.