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: AuthContextLocal.java,v 1.12 2009/05/21 21:57:34 qcheng Exp $
026 *
027 */
028
029/*
030 * Portions Copyright 2013 ForgeRock AS
031 */
032
033package com.sun.identity.authentication.server;
034
035import com.iplanet.sso.SSOToken;
036import com.sun.identity.authentication.AuthContext;
037import com.sun.identity.authentication.service.AMLoginContext;
038import com.sun.identity.authentication.service.LoginState;
039import com.sun.identity.authentication.service.LoginStatus;
040import com.sun.identity.authentication.spi.AuthLoginException;
041import com.sun.identity.authentication.spi.PagePropertiesCallback;
042import com.sun.identity.authentication.util.ISAuthConstants;
043import com.sun.identity.policy.PolicyException;
044import com.sun.identity.policy.util.PolicyDecisionUtils;
045import com.sun.identity.shared.encode.URLEncDec;
046import com.sun.identity.shared.debug.Debug;
047import com.sun.identity.shared.locale.Locale;
048import java.security.Principal;
049import java.util.ArrayList;
050import java.util.Collections;
051import java.util.HashMap;
052import java.util.List;
053import java.util.Map;
054import java.util.ResourceBundle;
055import java.util.Set;
056import javax.security.auth.Subject;
057import javax.security.auth.callback.Callback;
058import javax.servlet.http.HttpSession;
059
060/**
061 * The <code>AuthContextLocal</code> provides the implementation for
062 * authenticating users.
063 * <p>
064 * A typical caller instantiates this class and starts the login process.
065 * The caller then obtains an array of <code>Callback</code> objects,
066 * which contains the information required by the authentication plug-in
067 * module. The caller requests information from the user. On receiving
068 * the information from the user, the caller submits the same to this class.
069 * If more information is required, the above process continues until all
070 * the information required by the plug-ins/authentication modules, has
071 * been supplied. The caller then checks if the user has successfully
072 * been authenticated. If successfully authenticated, the caller can
073 * then get the <code>Subject</code> and <code>SSOToken</code> for the user;
074 * if not successfully authenticated, the caller obtains the AuthLoginException.
075 * <p>
076 * The implementation supports authenticating users either locally
077 * i.e., in process with all authentication modules configured or remotely
078 * to an authentication service/framework. (See documentation to configure
079 * in either of the modes).
080 * <p>
081 * The <code>getRequirements()</code> and <code>submitRequirements()</code> 
082 * are used to pass the user credentials for authentication by the plugin 
083 * modules,<code>getStatus()</code> returns the authentication status.
084 * <p>
085 * It should be serializable as a requirement to be stored in HttpSession.
086 *
087 * @supported.api
088 */
089public final class AuthContextLocal extends Object
090    implements java.io.Serializable {
091
092    /*
093     * Protected variables used locally
094     */
095
096    // Debug & I18N class
097    private static final String amAuthContextLocal = "amAuthContextLocal";
098    /**
099     * Hold the debug instance
100     */
101    protected static Debug authDebug = Debug.getInstance(amAuthContextLocal);
102    
103    /**
104     * Holds the locale-specific information 
105     */
106    protected static ResourceBundle bundle =
107        Locale.getInstallResourceBundle(amAuthContextLocal);
108
109    /**
110     * Holds organizationName
111     */
112    protected String organizationName;
113    /**
114     * Holds the set of module instance names
115     */
116    protected Set moduleInstanceNames;
117    /**
118     * Holds the index type
119     */
120    protected AuthContext.IndexType indexType;
121    /**
122     * Holds the index name
123     */
124    protected String indexName;
125    /**
126     * Holds the login status
127     */
128    protected AuthContext.Status loginStatus;
129    /**
130     * Holds the host name
131     */
132    protected String hostName;
133    /**
134     * Holds the http session
135     */
136    protected HttpSession httpSession;
137    /**
138     * Holds Single Sign on Token
139     */
140    protected SSOToken ssoToken;
141    /**
142     * AuthLoginException
143     */
144    protected volatile AuthLoginException loginException = null;
145    /**
146     * Holds call back information
147     */
148    protected Callback[] informationRequired = null;
149    /**
150     * AuthLoginContext
151     */
152    public AMLoginContext amlc = null;
153    /**
154     * Holds LoginStatus
155     */
156    public LoginStatus ls;
157    /**
158     * Holds subject
159     */
160    protected Subject subject;
161    /**
162     * character array for password
163     */
164    protected char[] password;
165    
166    private LoginState loginState = null;
167
168    private String orgDN = null;
169    
170    /**
171     * Holds information about submittion of requirements
172     */
173    private boolean inSubmitRequirements = false;
174
175    /**
176     * Creates <code>AuthContextLocal</code> instance is obtained for a given
177     * organization name, or sub organization name. <code>login</code> method is
178     * then used to start the authentication process.
179     *
180     * @param orgName name of the user's organization.
181     *
182     * @supported.api
183     */
184    public AuthContextLocal(String orgName) {
185        authDebug.message("AuthContextLocal() constructor called");
186        organizationName = orgName;
187
188        amlc = new AMLoginContext(this);
189        if (authDebug.messageEnabled()) {
190            authDebug.message("AMLoginContext object is... " + amlc);
191        }
192        reset();
193    }
194
195    /**
196     * Returns authentication module/s instances(or) plugin(s) configured
197     * for an organization, or sub-organization that was set during the
198     * <code>AuthContext</code> constructor.
199     *
200     * @return authentication module/s instances (or plugins).
201     * @throws UnsupportedOperationException if an error occurred.
202     *
203     * @supported.api
204     */
205    public Set getModuleInstanceNames() {
206        moduleInstanceNames = amlc.getModuleInstanceNames();
207
208        return (moduleInstanceNames);
209    }
210
211    /**
212     * Starts the login process for the given <code>AuthContextLocal</code>
213     * object.
214     *
215     * @exception AuthLoginException if an error occurred during login.
216     * @supported.api
217     */
218    public void login() throws AuthLoginException {
219        login(null);
220    }
221    
222    /**
223     * Starts the login process for the given <code>AuthContextLocal</code>s
224     * object for the given <code>Principal</code> and the user's password.
225     * This method should be called primarily
226     * when the authenticator knows there would no other
227     * credentials needed to complete the authentication process.
228     *
229     * @param principal <code>Principal</code> of the user to be authenticated.
230     * @param password password for the user.
231     * @throws AuthLoginException if an error occurred 
232     *            during login.
233     * @supported.api
234     */
235    public void login(Principal principal, char[] password) 
236        throws AuthLoginException {
237
238        // Make sure principal and password are not null
239        if (principal == null)
240            throw new AuthLoginException(amAuthContextLocal, 
241                "invalid-username", null);
242        if (password == null)
243            throw new AuthLoginException(amAuthContextLocal, 
244                "invalid-password", null);
245
246        // Copy the password
247        this.password = password;
248
249        login(null, null, principal, password, null, false);
250    }
251
252    /**
253     * Start the login process for the <code>AuthContextLocal</code> object
254     * identified by the index type and index name.
255     * The <code>IndexType</code> defines the possible kinds
256     * of "objects" or "resources" for which an authentication can
257     * be performed.  Currently supported index types are
258     * users, roles, services (or application), levels and mechanism.
259     *
260     * @param type authentication index type.
261     * @param indexName authentication index name.
262     * @throws AuthLoginException if an error occurred 
263     *            during login.
264     * @supported.api
265     */
266    public void login(AuthContext.IndexType type, String indexName)
267        throws AuthLoginException {
268        if (authDebug.messageEnabled()) {
269            authDebug.message("AuthContextLocal::login() called " +
270            "with IndexType : " + type + " & Indexname : " + indexName);
271        }
272
273        login(type, indexName, null, null, null, false);
274    }
275
276    /**
277     * Starts the login process for the given <code>AuthContextLocal</code>
278     * object for the given <code>Subject</code>.
279     * Refer to JAAS for description on <code>Subject</code>.
280     *
281     * @param subject <code>Subject</code> of the user to be authenticated.
282     * @throws AuthLoginException if an error occurred 
283     *            during login.
284     * @supported.api
285     */
286    public void login(Subject subject) throws AuthLoginException {
287        login(null, null, null, null, subject, false);
288    }
289
290    /**
291     * Starts the login process for the given <code>AuthContextLocal</code>
292     * object identified by the index type and index name.
293     * The <code>IndexType</code> defines the possible kinds
294     * of "objects" or "resources" for which an authentication can
295     * be performed.Currently supported index types are
296     * users, roles, services (or application), levels and mechanism.
297     * The pCookieMode indicates that a persistent cookie exists
298     * for this request.
299     *
300     * @param type authentication index type.
301     * @param indexName authentication index name.
302     * @param locale locale setting.
303     * @throws AuthLoginException if an error occurred during 
304     *            login process.
305     */
306    public void login(
307        AuthContext.IndexType type,
308        String indexName,
309        String locale
310    ) throws AuthLoginException {
311        if (authDebug.messageEnabled()) {
312            authDebug.message("AuthContextLocal::login() called " +
313            "with IndexType : " + type + " & Indexname : " + indexName +
314            " & locale : " + locale);
315        }
316
317        login(type, indexName, null, null, null, false, null, locale);
318    }
319
320    /**
321     * Starts the login process for the given <code>AuthContextLocal</code>
322     * object identified by the index type and index name.
323     * The <code>IndexType</code> defines the possible kinds
324     * of "objects" or "resources" for which an authentication can
325     * be performed.Currently supported index types are
326     * users, roles, services (or application), levels and mechanism.
327     * The pCookieMode indicates that a persistent cookie exists
328     * for this request.
329     *
330     * @param type authentication index type.
331     * @param indexName authentication index name.
332     * @param pCookieMode <code>true</code> if persistent Cookie exists,
333     *        <code>false</code> otherwise
334     * @throws AuthLoginException if an error occurred during 
335     *            login process.
336     */
337    public void login(
338        AuthContext.IndexType type,
339        String indexName,
340        boolean pCookieMode
341    ) throws AuthLoginException {
342        if (authDebug.messageEnabled()) {
343            authDebug.message("AuthContextLocal::login() called " +
344            "with IndexType : " + type + " & Indexname : " + indexName +
345            " & pCookieMode : " + pCookieMode);
346        }
347
348        login(type, indexName, null, null, null, pCookieMode);
349    }
350
351    /**
352     * Starts the login process for the given <code>AuthContextLocal</code>
353     * object identified by the index type and index name.
354     * The <code>IndexType</code> defines the possible kinds
355     * of "objects" or "resources" for which an authentication can
356     * be performed.Currently supported index types are
357     * users, roles, services (or application), levels and mechanism.
358     * The pCookieMode indicates that a persistent cookie exists
359     * for this request.
360     * The locale specifies the user preferred locale setting.
361     *
362     * @param type authentication index type.
363     * @param indexName authentication index name.
364     * @param pCookieMode <code>true</code> if persistent Cookie exists,
365     *        <code>false</code> otherwise
366     * @param locale locale setting.
367     * @throws AuthLoginException if an error occurred during 
368     *            login process.
369     */
370    public void login(
371        AuthContext.IndexType type,
372        String indexName,
373        boolean pCookieMode,
374        String locale
375    ) throws AuthLoginException {
376        if (authDebug.messageEnabled()) {
377            authDebug.message("AuthContextLocal::login() called " +
378            "with IndexType : " + type + " & Indexname : " + indexName +
379            " & pCookieMode : " + pCookieMode + " & locale : " + locale);
380        }
381        login(type, indexName, null, null, null, pCookieMode, null, locale);
382    }
383    
384    /**
385     * Starts the login process for the given <code>AuthContextLocal</code>
386     * object identified by the index type and index name.
387     * The <code>IndexType</code> defines the possible kinds
388     * of "objects" or "resources" for which an authentication can
389     * be performed.Currently supported index types are
390     * users, roles, services (or application), levels and mechanism.
391     * The pCookieMode indicates that a persistent cookie exists
392     * for this request.
393     * The locale specifies the user preferred locale setting.
394     *
395     * @param type authentication index type.
396     * @param indexName authentication index name.
397     * @param pCookieMode <code>true</code> if persistent Cookie exists,
398     *        <code>false</code> otherwise
399     * @param envMap Environment Map, key is String, value is set of string.
400     *        this is applicable only when the type is 
401     *        <code>AuthContext.IndexType.RESOURCE</code>
402     * @param locale locale setting.
403     * @throws AuthLoginException if an error occurred during 
404     *            login process.
405     */
406    public void login(
407        AuthContext.IndexType type,
408        String indexName,
409        boolean pCookieMode, 
410        Map envMap,
411        String locale
412    ) throws AuthLoginException {
413        if (authDebug.messageEnabled()) {
414            authDebug.message("AuthContextLocal::login() called " +
415            "with IndexType : " + type + " & Indexname : " + indexName +
416            " & pCookieMode : " + pCookieMode + " & locale : " + locale +
417            " & envMap : " + envMap);
418        }
419        login(type, indexName, null, null, null, pCookieMode, envMap, locale);
420    }
421
422    /**
423     * Performs the Login for the given AuthContext
424     * @param type authentication index type
425     * @param indexName authentication index name
426     * @param principal principal name of the user to be authenticated
427     * @param password password for the user
428     * @param subject authentication subject
429     * @param pCookieMode <code>true</code>persistent Cookie exists,
430     *        <code>false</code> otherwise
431     * @throws AuthLoginException if error occurs during login
432     */
433    protected void login(AuthContext.IndexType type, String indexName, 
434        Principal principal, char[] password, Subject subject, 
435        boolean pCookieMode) throws AuthLoginException {
436        login(type, indexName, principal, password, subject, pCookieMode, 
437            null, null);
438    }
439
440    /**
441     * Performs the Login for the given AuthContext
442     * @param type authentication index type
443     * @param indexName authentication index name
444     * @param principal principal name of the user to be authenticated
445     * @param password password for the user
446     * @param subject authentication subject
447     * @param pCookieMode <code>true</code>persistent Cookie exists,
448     *        <code>false</code> otherwise
449     * @param envMap Environment map, this is applicable only when the type
450     *        is <code>AuthContext.IndexType.RESOURCE</code>
451     * @param locale locale setting
452     * @throws AuthLoginException if error occurs during login
453     */
454    protected void login(AuthContext.IndexType type, String indexName, 
455        Principal principal, char[] password, Subject subject, 
456        boolean pCookieMode, Map envMap, String locale) 
457        throws AuthLoginException {
458        try {
459            /*if (!getStatus().equals(AuthContext.Status.NOT_STARTED)) {
460                if (authDebug.messageEnabled()) {
461                    authDebug.message("AuthContextLocal::login called " +
462                    "when the current login status is : " + getStatus());
463                }
464                throw new AuthLoginException(amAuthContextLocal, 
465                    "invalidMethod", new Object[]{getStatus()});
466            }*/
467
468            // switch the login status
469            loginStatus = AuthContext.Status.IN_PROGRESS;
470
471            String redirectUrl = null;
472            // specially processing for resouce/IP/Environement based auth
473            if ((type != null) && type.equals(AuthContext.IndexType.RESOURCE)) { 
474                // this is resouce/IP/Env based authentication
475                // call Policy Decision Util to find out the actual auth type 
476                // required by policy
477                List result = Collections.EMPTY_LIST;
478                try {
479                    result = PolicyDecisionUtils.doResourceIPEnvAuth(
480                            indexName, organizationName, envMap);
481                } catch (PolicyException pe) {
482                    // ignore, continue to default realm based authentication
483                    // may need to revisit this in the future
484                    authDebug.warning("AuthContextLocal.login() policy error " +
485                        "indexName=" + indexName, pe);
486                    type = null;
487                    indexName = null;
488                }
489                if (authDebug.messageEnabled()) {
490                    authDebug.message("AuthContextLocal.login: policy decision="
491                        + result);
492                }
493                if (result.size() == 2) {
494                    type = (AuthContext.IndexType) result.get(0);
495                    indexName = (String) result.get(1);
496                } else if (result.size() == 1) {
497                    // this is the redirection case (Policy Redirection Advice)
498                    redirectUrl = (String) result.get(0);
499                    // append goto parameter for federation case
500                    Set tmp = (Set) envMap.get(ISAuthConstants.GOTO_PARAM);
501                    if ((tmp != null) && !tmp.isEmpty()) {
502                        String gotoParam = (String) tmp.iterator().next();
503                        if ((gotoParam != null) && (gotoParam.length() != 0)) {
504                            if ((redirectUrl != null) && 
505                                (redirectUrl.indexOf("?") != -1)) {
506                                redirectUrl = redirectUrl + "&" + 
507                                    ISAuthConstants.GOTO_PARAM + "=" + 
508                                    URLEncDec.encode(gotoParam);
509                            } else {
510                                redirectUrl = redirectUrl + "?" + 
511                                    ISAuthConstants.GOTO_PARAM + "=" + 
512                                    URLEncDec.encode(gotoParam);
513                            }
514                        }
515                    }
516                    type = null;
517                    indexName = null;
518                } else {
519                    // no policy decision, use default realm login
520                    type = null;
521                    indexName = null;
522                }
523
524            }
525            HashMap loginParamsMap = new HashMap();
526
527            loginParamsMap.put(INDEX_TYPE, type);
528            loginParamsMap.put(INDEX_NAME, indexName);
529            loginParamsMap.put(PRINCIPAL, principal);
530            loginParamsMap.put(PASSWORD, password);
531            loginParamsMap.put(SUBJECT, subject);
532            loginParamsMap.put(PCOOKIE, Boolean.valueOf(pCookieMode));
533            loginParamsMap.put(LOCALE, locale);
534            if (redirectUrl != null) {
535                loginParamsMap.put(REDIRECT_URL, redirectUrl);
536            }
537
538            if (authDebug.messageEnabled()) {
539                authDebug.message(
540                    "loginParamsMap : " + loginParamsMap.toString());
541            }
542
543            authDebug.message("calling AMLoginContext::exceuteLogin : ");
544            amlc.executeLogin(loginParamsMap);
545            authDebug.message("after AMLoginContext::exceuteLogin : ");
546            if (amlc.getStatus() == LoginStatus.AUTH_SUCCESS) {
547                loginStatus = AuthContext.Status.SUCCESS;
548            } else if (amlc.getStatus() == LoginStatus.AUTH_FAILED) {
549                loginStatus = AuthContext.Status.FAILED;
550            }
551            if (authDebug.messageEnabled()) {
552                authDebug.message(
553                    "Status at the end of login() : " + loginStatus);
554            }
555        } catch (AuthLoginException e) {
556            if (authDebug.messageEnabled()) {
557                authDebug.message("Exception in ac.login : " + e.toString());
558            }
559            throw e;
560        }
561    }
562
563    /**
564     * Resets this instance of <code>AuthContextLocal</code>
565     * object, so that a new login process can be initiated.
566     * A new authentication process can started using any
567     * one of the <code>login</code> methods.
568     */
569    public void reset() {
570        authDebug.message("AuthContextLocal::reset() called");
571        loginStatus = AuthContext.Status.NOT_STARTED;
572        informationRequired = null;
573        loginException = null;
574    }
575
576    /**
577     * Returns the set of Principals the user has been authenticated as.
578     * This should be invoked only after successful authentication.
579     * If the authentication fails or the authentication is in process,
580     * this will return <code>null</code>.
581     *
582     * @return The set of Principals the user has been authenticated as.
583     * @supported.api
584     */
585    public Subject getSubject() {
586        if (!loginStatus.equals(AuthContext.Status.SUCCESS)) {
587            return (null);
588        }
589        if (subject == null) {
590            subject = amlc.getSubject();
591        }
592        return (subject);
593    }
594
595    /**
596     * Checks if the login process requires more information from the user to
597     * complete the authentication.
598     *
599     * @return <code>true</code> if more credentials are required
600     *         from the user.
601     * @supported.api
602     */
603    public boolean hasMoreRequirements() {
604        authDebug.message("AuthContextLocal::hasMoreRequirements()");
605
606        if ((amlc.getStatus() == LoginStatus.AUTH_SUCCESS) ||
607            (amlc.getStatus() == LoginStatus.AUTH_FAILED)
608        ) {
609            return false;
610        } else {
611            informationRequired = amlc.getRequiredInfo();
612            return (informationRequired != null);
613        }
614    }
615
616    /**
617     * Checks if the login process requires more information from the user to
618     * complete the authentication
619     * @param noFilter falg to indicate if there is a Filter
620     * @return <code>true</code> if more credentials are required
621     *         from the user.
622     */
623    public boolean hasMoreRequirements(boolean noFilter) {
624        authDebug.message("AuthContextLocal::hasMoreRequirements()");
625
626        if ((amlc.getStatus() == LoginStatus.AUTH_SUCCESS) ||
627            (amlc.getStatus() == LoginStatus.AUTH_FAILED)
628        ) {
629            return false;
630        } else {
631            informationRequired = amlc.getRequiredInfo();
632            return (getCallbacks(informationRequired, noFilter) != null);
633        }
634    }
635
636    /**
637     * Returns an array of <code>Callback</code> objects that
638     * must be populated by the user and returned back.
639     * These objects are requested by the authentication plug-ins,
640     * and these are usually displayed to the user. The user then provides
641     * the requested information for it to be authenticated.
642     *
643     * @return an array of <code>Callback</code> objects requesting credentials
644     *         from user.
645     * @supported.api
646     */
647    public Callback[] getRequirements() {
648        authDebug.message("AuthContextLocal::getRequirements()");
649
650        if ((amlc.getStatus() == LoginStatus.AUTH_SUCCESS) ||
651            (amlc.getStatus() == LoginStatus.AUTH_FAILED)
652        ) {
653            return null;
654        } else {
655            return (informationRequired);
656        }
657    }
658
659    /**
660     * Returns an array of <code>Callback</code> objects that
661     * must be populated by the user and returned back.
662     * These objects are requested by the authentication plug-ins,
663     * and these are usually displayed to the user. The user then provides
664     * the requested information for it to be authenticated.
665     *
666     * @param noFilter flag to indicate if there is a Filter
667     * @return an array of <code>Callback</code> objects requesting credentials
668     *         from user.
669     * @supported.api
670     */
671    public Callback[] getRequirements(boolean noFilter) {
672        authDebug.message("AuthContextLocal::getRequirements()");
673
674        if ((amlc.getStatus() == LoginStatus.AUTH_SUCCESS) ||
675            (amlc.getStatus() == LoginStatus.AUTH_FAILED)
676        ) {
677            return null;
678        } else {
679            return (getCallbacks(informationRequired, noFilter));
680        }
681    }
682
683    /**
684     * Submit the populated <code>Callback</code> objects
685     * to the authentication plug-in modules. Called after
686     * <code>getRequirements</code> method and obtaining
687     * user's response to these requests.
688     *
689     * @param info array of <code>Callback</code> objects
690     * @supported.api
691     */
692    public void submitRequirements(Callback[] info) {
693        authDebug.message("AuthContextLocal::submitRequirements()");
694        inSubmitRequirements = true;
695        try{
696           informationRequired = null;
697           amlc.submitRequiredInfo(info) ;
698           if (!amlc.isPureJAAS()) {
699                amlc.runLogin();
700           }
701           if (amlc.getStatus() == LoginStatus.AUTH_SUCCESS) {
702                loginStatus = AuthContext.Status.SUCCESS;
703           } else if (amlc.getStatus() == LoginStatus.AUTH_FAILED) {
704                loginStatus = AuthContext.Status.FAILED;
705           }
706           authDebug.message("AuthContextLocal::submitRequirements end");
707           if (authDebug.messageEnabled()) {
708                authDebug.message("Status at the end of submitRequirements() : "
709                                + loginStatus);
710           }
711         } finally {
712           inSubmitRequirements = false;
713         }
714    }
715
716    /**
717     * Logs out the user and also invalidates the <code>SSOToken</code>
718     * associated with this <code>AuthContextLocal</code>.
719     *
720     * @throws AuthLoginException if an error occurred during logout
721     * @supported.api
722     */
723    public void logout() throws AuthLoginException {
724        authDebug.message("AuthContextLocal::logout()");
725
726        try {
727            amlc.logout();
728        } catch (Exception e) {
729            if (authDebug.messageEnabled()) {
730                authDebug.message("Exception in AMLoginContext::logout() "
731                    + e.getMessage());
732            }
733            throw new AuthLoginException(amAuthContextLocal, "logoutError",
734                null, e);
735        }
736
737        authDebug.message("Called AMLoginContext::logout()");
738        loginStatus = AuthContext.Status.COMPLETED;
739    }
740
741    /**
742     * Returns login exception, if any, during
743     * the authentication process. Typically set when the login
744     * fails.
745     *
746     * @return login exception.
747     * @supported.api
748     */
749    public AuthLoginException getLoginException() {
750        authDebug.message("AuthContextLocal::getLoginException()");
751        return (loginException);
752    }
753
754    /**
755     * Sets the login exception that represents errors during the 
756     * authentication process.
757     *
758     * @param exception AuthLoginException to be set.
759     */
760    public void setLoginException(AuthLoginException exception) {
761        loginException = exception;
762    }
763
764    /**
765     * Returns the current status of the authentication process.
766     *
767     * @return the current status of the authentication process.
768     * @supported.api
769     */
770    public AuthContext.Status getStatus() {
771        authDebug.message("AuthContextLocal::getStatus()");
772        if (amlc.getStatus() == LoginStatus.AUTH_SUCCESS) {
773            loginStatus = AuthContext.Status.SUCCESS;
774        }
775        else if (amlc.getStatus() == LoginStatus.AUTH_FAILED) {
776            loginStatus = AuthContext.Status.FAILED;
777        }
778        else if (amlc.getStatus() == LoginStatus.AUTH_RESET) {
779            loginStatus =  AuthContext.Status.RESET;
780        }
781        else if (amlc.getStatus() == LoginStatus.AUTH_ORG_MISMATCH) {
782            loginStatus =  AuthContext.Status.ORG_MISMATCH;
783        }
784        else if (amlc.getStatus() == LoginStatus.AUTH_IN_PROGRESS) {
785            loginStatus =  AuthContext.Status.IN_PROGRESS;
786        }
787        else if (amlc.getStatus() == LoginStatus.AUTH_COMPLETED) {
788            loginStatus =  AuthContext.Status.COMPLETED;
789        }
790
791
792        if (authDebug.messageEnabled()) {
793            authDebug.message("AuthContextLocal:: Status : " + loginStatus);
794        }
795
796        return (loginStatus);
797    }
798
799    /**
800     * Sets the login status. Used internally and
801     * not visible outside this package.
802     * @param status login status
803     */
804    protected void setLoginStatus(AuthContext.Status status) {
805        authDebug.message("AuthContextLocal::setLoginStatus()");
806        loginStatus = status;
807    }
808
809    /**
810     * Returns the Single-Sign-On (SSO) Token for the authenticated
811     * user.Single-Sign-On token can be used as the authenticated token.
812     *
813     * @return single-sign-on token
814     * @supported.api
815     */
816    public SSOToken getSSOToken() {
817        ssoToken = amlc.getSSOToken();
818        return (ssoToken);
819    }
820
821    /**
822     * Returns the Successful Login URL for the authenticated user.
823     * 
824     * @return the Successful Login URL for the authenticated user.
825     */
826    public String getSuccessURL() {        
827        return amlc.getSuccessURL();        
828    }
829    
830    /**
831     * Returns the Failure Login URL for the authenticating user.
832     * 
833     * @return the Failure Login URL for the authenticating user.
834     */
835    public String getFailureURL() {        
836        return amlc.getFailureURL();        
837    }
838    
839    /**
840     * Returns the the organization name that was set during the
841     * <code>AuthContextLocal</code> constructor.
842     *
843     * @return Organization name.
844     *
845     * @supported.api
846     */
847    public String getOrganizationName() {
848        return (amlc.getOrganizationName());
849    }
850
851    /**
852     * Terminates an ongoing <code>login</code> call that has not yet completed.
853     *
854     * @throws AuthLoginException if an error occurred during abort.
855     *
856     * @supported.api
857     */
858    public void abort() throws AuthLoginException {
859        authDebug.message("AuthContextLocal::abort()");
860
861        try {
862            amlc.abort();
863        } catch (Exception e) {
864            if (authDebug.messageEnabled()) {
865                authDebug.message("Exception in AMLoginContext::abort() "
866                + e.getMessage());
867            }
868            throw new AuthLoginException(amAuthContextLocal, "abortError", 
869                null, e);
870        }
871
872        loginStatus = AuthContext.Status.COMPLETED;
873    }
874
875    /**
876     * Returns the error template.
877     *
878     * @return the error template.
879     */
880    public String getErrorTemplate() {
881        return amlc.getErrorTemplate();
882    }
883
884    /**
885     * Returns the error message.
886     *
887     * @return the error message.
888     */
889    public String getErrorMessage() {
890        return amlc.getErrorMessage();
891    }
892
893    /**
894     * Returns the error code.
895     *
896     * @return error code.
897     */
898    public String getErrorCode() {
899        return amlc.getErrorCode();
900    }
901
902    /**
903     * Returns the current 'authIdentifier' of the authentication process as
904     * String Session ID.
905     *
906     * @return <code>authIdentifier</code> of the authentication process
907     */
908    public String getAuthIdentifier() {        
909        return amlc.getAuthIdentifier();
910    }
911    
912    /**
913     * Returns the account lockout message. This can be either a dynamic
914     * message indicating the number of tries left or the the account
915     * deactivated message.
916     *
917     * @return account lockout message.
918     */
919    public String getLockoutMsg() {
920
921        String lockoutMsg = amlc.getLockoutMsg();
922
923        if (authDebug.messageEnabled()) {
924            authDebug.message("getLockoutMsg: lockoutMsg: " + lockoutMsg);
925        }
926
927        return lockoutMsg;
928    }
929
930    /**
931     * Checks the account is locked out
932     * @return <code>true</code> if the account is locked,
933     *         <code>false</code> otherwise
934     */
935    public boolean isLockedOut() {
936        boolean isLockedOut = amlc.isLockedOut();
937        if (authDebug.messageEnabled()) {
938            authDebug.message("isLockedOut : " + isLockedOut);
939        }
940
941        return isLockedOut;
942    }
943
944    /**
945     * Sets the client's host name , this method is used in case of remote 
946     * authentication,to set the client's hostname or IP address. 
947     * This could be used by the policy component to restrict access 
948     * to resources.
949     *
950     * @param hostname Host name.
951     */
952    public void setClientHostName(String hostname) {
953        hostName = hostname;
954    }
955
956    /**
957     * Returns the clients host name
958     * @return hostname
959     */
960    protected String getClientHostName() {
961        return (hostName);
962    }
963
964    public boolean submittedRequirements() {
965        return inSubmitRequirements;
966    }
967
968    /**
969     * Sets the <code>HttpSession</code> that will be used by
970     * the SSO component to store the session information. In the
971     * absence of <code>HttpSession</code> the information is stored
972     * in <code>HashMap</code> and will have issues with fail-over.
973     * With session fail-over turned on <code>HttpSession</code>
974     * would be provide persistance storage mechanism for SSO.
975     *
976     * @param session HttpSession
977     */
978    public void setHttpSession(HttpSession session) {
979        httpSession = session;
980    }
981
982    /**
983     * Returns the <code>HTTPSession</code> associated with the current
984     * authentication context
985     * @return httpSession
986     */
987    protected HttpSession getHttpSession() {
988        return (httpSession);
989    }
990
991    /**
992     * Returns the array of <code>Callback</code> requirements objects
993     * @param recdCallbacks callbacks requirements
994     * @param noFilter boolean to indicate if filter exists
995     * @return an array of <code>Callback</code> objects
996     */
997    protected static Callback[] getCallbacks(
998        Callback[] recdCallbacks,
999        boolean noFilter) {
1000        if (recdCallbacks == null) {
1001            return (null);
1002        } else if (noFilter) {
1003            return recdCallbacks;
1004        } else {
1005            Callback[] answer = new Callback[0];
1006            ArrayList callbackList= new ArrayList(); 
1007
1008            for (int i = 0; i < recdCallbacks.length; i++) {
1009                if (authDebug.messageEnabled()) {
1010                    authDebug.message("In getCallbacks() callback : "
1011                      + recdCallbacks[i]);
1012                }
1013                if (!(recdCallbacks[i] instanceof PagePropertiesCallback)) {
1014                     callbackList.add(recdCallbacks[i]);
1015                } 
1016            }
1017            return (Callback[]) callbackList.toArray(answer);
1018        }
1019    }
1020
1021    /**
1022     * Sets the Login State
1023     * @param state login state
1024     */
1025    public void setLoginState(LoginState state) {
1026        loginState = state;
1027    } 
1028
1029    /**
1030     * Returns the login state
1031     * @return loginState
1032     */
1033    public LoginState getLoginState() {
1034        return loginState;
1035    }
1036
1037    /**
1038     * Sets the Organization DN
1039     * @param orgDN Organization DN
1040     */
1041    public void setOrgDN(String orgDN) {
1042        this.orgDN = orgDN;
1043    }
1044
1045    /**
1046     * Returns the Organization DN
1047     * @return the Organization DN 
1048     */
1049    public String getOrgDN() {
1050        return orgDN;
1051    }
1052
1053    /**
1054     * Holds LDAP URL
1055     */
1056    public final static String LDAP_AUTH_URL = "ldap://";
1057
1058    /**
1059     * Holds ersistent cookie mode
1060     */
1061    public final static String PCOOKIE = "pCookieMode";
1062    /**
1063     * Holds principal name to be authenticated
1064     */
1065    public final static String PRINCIPAL = "principal";
1066    /**
1067     * Holds Password for the user
1068     */
1069    public final static String PASSWORD = "password";
1070    /**
1071     * authentication subject
1072     */
1073    public final static String SUBJECT = "subject";
1074    /**
1075     * authentication index type
1076     */
1077    public final static String INDEX_TYPE = "indexType";
1078    
1079    /**
1080     * authentication index name
1081     */
1082    public final static String INDEX_NAME = "indexName";
1083
1084    /**
1085     * locale setting
1086     */
1087    public final static String LOCALE = "locale";
1088    
1089    /**
1090     * Redirection URL
1091     */
1092    public static final String REDIRECT_URL = "redirectionURL";
1093}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.