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 ctx = 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                            ctx = PortalLDAPUtil.getContext(ldapServerId, companyId);
155    
156                            if (ctx == 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 cons = new SearchControls(
181                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
182    
183                            NamingEnumeration<SearchResult> enu = ctx.search(
184                                    baseDN, filter, cons);
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 attrs = PortalLDAPUtil.getUserAttributes(
194                                            ldapServerId, companyId, ctx,
195                                            PortalLDAPUtil.getNameInNamespace(
196                                                    ldapServerId, companyId, binding));
197    
198                                    return PortalLDAPImporterUtil.importLDAPUser(
199                                            ldapServerId, companyId, ctx, attrs, StringPool.BLANK);
200                            }
201                            else {
202                                    return null;
203                            }
204                    }
205                    catch (Exception e) {
206                            if (_log.isWarnEnabled()) {
207                                    _log.warn("Problem accessing LDAP server " + e.getMessage());
208                            }
209    
210                            if (_log.isDebugEnabled()) {
211                                    _log.debug(e, e);
212                            }
213    
214                            throw new SystemException(
215                                    "Problem accessing LDAP server " + e.getMessage());
216                    }
217                    finally {
218                            if (ctx != null) {
219                                    ctx.close();
220                            }
221                    }
222            }
223    
224            protected User importLDAPUser(
225                            long companyId, String emailAddress, String screenName)
226                    throws Exception {
227    
228                    long[] ldapServerIds = StringUtil.split(
229                            PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
230    
231                    if (ldapServerIds.length <= 0) {
232                            ldapServerIds = new long[] {0};
233                    }
234    
235                    for (long ldapServerId : ldapServerIds) {
236                            User user = importLDAPUser(
237                                    ldapServerId, companyId, emailAddress, screenName);
238    
239                            if (user != null) {
240                                    return user;
241                            }
242                    }
243    
244                    if (_log.isDebugEnabled()) {
245                            if (Validator.isNotNull(emailAddress)) {
246                                    _log.debug(
247                                            "User with the email address " + emailAddress +
248                                                    " was not found in any LDAP servers");
249                            }
250                            else {
251                                    _log.debug(
252                                            "User with the screen name " + screenName +
253                                                    " was not found in any LDAP servers");
254                            }
255                    }
256    
257                    return null;
258            }
259    
260            private static Log _log = LogFactoryUtil.getLog(CASAutoLogin.class);
261    
262    }