001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.auth;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.ParamUtil;
021    import com.liferay.portal.kernel.util.PropsKeys;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.model.CompanyConstants;
026    import com.liferay.portal.model.User;
027    import com.liferay.portal.security.ldap.LDAPSettingsUtil;
028    import com.liferay.portal.security.ldap.PortalLDAPImporterUtil;
029    import com.liferay.portal.security.ldap.PortalLDAPUtil;
030    import com.liferay.portal.service.UserLocalServiceUtil;
031    import com.liferay.portal.servlet.filters.sso.cas.CASFilter;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portal.util.PrefsPropsUtil;
034    import com.liferay.portal.util.PropsValues;
035    
036    import javax.naming.Binding;
037    import javax.naming.NamingEnumeration;
038    import javax.naming.directory.Attributes;
039    import javax.naming.directory.SearchControls;
040    import javax.naming.directory.SearchResult;
041    import javax.naming.ldap.LdapContext;
042    
043    import javax.servlet.http.HttpServletRequest;
044    import javax.servlet.http.HttpServletResponse;
045    import javax.servlet.http.HttpSession;
046    
047    /**
048     * @author Brian Wing Shun Chan
049     * @author Jorge Ferrer
050     * @author Wesley Gong
051     * @author Daeyoung Song
052     */
053    public class CASAutoLogin implements AutoLogin {
054    
055            public String[] login(
056                    HttpServletRequest request, HttpServletResponse response) {
057    
058                    String[] credentials = null;
059    
060                    try {
061                            long companyId = PortalUtil.getCompanyId(request);
062    
063                            if (!PrefsPropsUtil.getBoolean(
064                                            companyId, PropsKeys.CAS_AUTH_ENABLED,
065                                            PropsValues.CAS_AUTH_ENABLED)) {
066    
067                                    return credentials;
068                            }
069    
070                            HttpSession session = request.getSession();
071    
072                            String login = (String)session.getAttribute(CASFilter.LOGIN);
073    
074                            if (Validator.isNull(login)) {
075                                    return credentials;
076                            }
077    
078                            String authType = PrefsPropsUtil.getString(
079                                    companyId, PropsKeys.COMPANY_SECURITY_AUTH_TYPE,
080                                    PropsValues.COMPANY_SECURITY_AUTH_TYPE);
081    
082                            User user = null;
083    
084                            if (PrefsPropsUtil.getBoolean(
085                                            companyId, PropsKeys.CAS_IMPORT_FROM_LDAP,
086                                            PropsValues.CAS_IMPORT_FROM_LDAP)) {
087    
088                                    try {
089                                            if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
090                                                    user = importLDAPUser(
091                                                            companyId, StringPool.BLANK, login);
092                                            }
093                                            else {
094                                                    user = importLDAPUser(
095                                                            companyId, login, StringPool.BLANK);
096                                            }
097                                    }
098                                    catch (SystemException se) {
099                                    }
100                            }
101    
102                            if (user == null) {
103                                    if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
104                                            user = UserLocalServiceUtil.getUserByScreenName(
105                                                    companyId, login);
106                                    }
107                                    else {
108                                            user = UserLocalServiceUtil.getUserByEmailAddress(
109                                                    companyId, login);
110                                    }
111                            }
112    
113                            String redirect = ParamUtil.getString(request, "redirect");
114    
115                            if (Validator.isNotNull(redirect)) {
116                                    request.setAttribute(AutoLogin.AUTO_LOGIN_REDIRECT, redirect);
117                            }
118    
119                            credentials = new String[3];
120    
121                            credentials[0] = String.valueOf(user.getUserId());
122                            credentials[1] = user.getPassword();
123                            credentials[2] = Boolean.TRUE.toString();
124    
125                            return credentials;
126                    }
127                    catch (Exception e) {
128                            _log.error(e, e);
129                    }
130    
131                    return credentials;
132            }
133    
134            /**
135             * @deprecated Use <code>importLDAPUser</code>.
136             */
137            protected User addUser(long companyId, String screenName) throws Exception {
138                    return importLDAPUser(companyId, StringPool.BLANK, screenName);
139            }
140    
141            protected User importLDAPUser(
142                            long ldapServerId, long companyId, String emailAddress,
143                            String screenName)
144                    throws Exception {
145    
146                    LdapContext ldapContext = null;
147    
148                    try {
149                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
150    
151                            String baseDN = PrefsPropsUtil.getString(
152                                    companyId, PropsKeys.LDAP_BASE_DN + postfix);
153    
154                            ldapContext = PortalLDAPUtil.getContext(ldapServerId, companyId);
155    
156                            if (ldapContext == null) {
157                                    throw new SystemException("Failed to bind to the LDAP server");
158                            }
159    
160                            String filter = PrefsPropsUtil.getString(
161                                    companyId, PropsKeys.LDAP_AUTH_SEARCH_FILTER + postfix);
162    
163                            if (_log.isDebugEnabled()) {
164                                    _log.debug("Search filter before transformation " + filter);
165                            }
166    
167                            filter = StringUtil.replace(
168                                    filter,
169                                    new String[] {
170                                            "@company_id@", "@email_address@", "@screen_name@"
171                                    },
172                                    new String[] {
173                                            String.valueOf(companyId), emailAddress, screenName
174                                    });
175    
176                            if (_log.isDebugEnabled()) {
177                                    _log.debug("Search filter after transformation " + filter);
178                            }
179    
180                            SearchControls searchControls = new SearchControls(
181                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
182    
183                            NamingEnumeration<SearchResult> enu = ldapContext.search(
184                                    baseDN, filter, searchControls);
185    
186                            if (enu.hasMoreElements()) {
187                                    if (_log.isDebugEnabled()) {
188                                            _log.debug("Search filter returned at least one result");
189                                    }
190    
191                                    Binding binding = enu.nextElement();
192    
193                                    Attributes attributes = PortalLDAPUtil.getUserAttributes(
194                                            ldapServerId, companyId, ldapContext,
195                                            PortalLDAPUtil.getNameInNamespace(
196                                                    ldapServerId, companyId, binding));
197    
198                                    return PortalLDAPImporterUtil.importLDAPUser(
199                                            ldapServerId, companyId, ldapContext, attributes,
200                                            StringPool.BLANK);
201                            }
202                            else {
203                                    return null;
204                            }
205                    }
206                    catch (Exception e) {
207                            if (_log.isWarnEnabled()) {
208                                    _log.warn("Problem accessing LDAP server " + e.getMessage());
209                            }
210    
211                            if (_log.isDebugEnabled()) {
212                                    _log.debug(e, e);
213                            }
214    
215                            throw new SystemException(
216                                    "Problem accessing LDAP server " + e.getMessage());
217                    }
218                    finally {
219                            if (ldapContext != null) {
220                                    ldapContext.close();
221                            }
222                    }
223            }
224    
225            protected User importLDAPUser(
226                            long companyId, String emailAddress, String screenName)
227                    throws Exception {
228    
229                    long[] ldapServerIds = StringUtil.split(
230                            PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
231    
232                    if (ldapServerIds.length <= 0) {
233                            ldapServerIds = new long[] {0};
234                    }
235    
236                    for (long ldapServerId : ldapServerIds) {
237                            User user = importLDAPUser(
238                                    ldapServerId, companyId, emailAddress, screenName);
239    
240                            if (user != null) {
241                                    return user;
242                            }
243                    }
244    
245                    if (_log.isDebugEnabled()) {
246                            if (Validator.isNotNull(emailAddress)) {
247                                    _log.debug(
248                                            "User with the email address " + emailAddress +
249                                                    " was not found in any LDAP servers");
250                            }
251                            else {
252                                    _log.debug(
253                                            "User with the screen name " + screenName +
254                                                    " was not found in any LDAP servers");
255                            }
256                    }
257    
258                    return null;
259            }
260    
261            private static Log _log = LogFactoryUtil.getLog(CASAutoLogin.class);
262    
263    }