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