001    /**
002     * Copyright (c) 2000-2012 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.servlet.filters.autologin;
016    
017    import com.liferay.portal.NoSuchUserException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.InstancePool;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.model.User;
027    import com.liferay.portal.security.auth.AutoLogin;
028    import com.liferay.portal.security.pwd.PwdEncryptor;
029    import com.liferay.portal.service.UserLocalServiceUtil;
030    import com.liferay.portal.servlet.filters.BasePortalFilter;
031    import com.liferay.portal.util.Portal;
032    import com.liferay.portal.util.PortalInstances;
033    import com.liferay.portal.util.PortalUtil;
034    import com.liferay.portal.util.PropsValues;
035    import com.liferay.portal.util.WebKeys;
036    
037    import java.util.List;
038    import java.util.concurrent.CopyOnWriteArrayList;
039    
040    import javax.servlet.FilterChain;
041    import javax.servlet.http.HttpServletRequest;
042    import javax.servlet.http.HttpServletResponse;
043    import javax.servlet.http.HttpSession;
044    
045    /**
046     * @author Brian Wing Shun Chan
047     * @author Raymond Augé
048     */
049    public class AutoLoginFilter extends BasePortalFilter {
050    
051            public static void registerAutoLogin(AutoLogin autoLogin) {
052                    _autoLogins.add(autoLogin);
053            }
054    
055            public static void unregisterAutoLogin(AutoLogin autoLogin) {
056                    _autoLogins.remove(autoLogin);
057            }
058    
059            public AutoLoginFilter() {
060                    for (String autoLoginClassName : PropsValues.AUTO_LOGIN_HOOKS) {
061                            AutoLogin autoLogin = (AutoLogin)InstancePool.get(
062                                    autoLoginClassName);
063    
064                            _autoLogins.add(autoLogin);
065                    }
066            }
067    
068            protected String getLoginRemoteUser(
069                            HttpServletRequest request, HttpServletResponse response,
070                            HttpSession session, String[] credentials)
071                    throws Exception {
072    
073                    if ((credentials == null) || (credentials.length != 3)) {
074                            return null;
075                    }
076    
077                    String jUsername = credentials[0];
078                    String jPassword = credentials[1];
079                    boolean encPassword = GetterUtil.getBoolean(credentials[2]);
080    
081                    if (Validator.isNull(jUsername) || Validator.isNull(jPassword)) {
082                            return null;
083                    }
084    
085                    try {
086                            long userId = GetterUtil.getLong(jUsername);
087    
088                            if (userId > 0) {
089                                    User user = UserLocalServiceUtil.getUserById(userId);
090    
091                                    if (user.isLockout()) {
092                                            return null;
093                                    }
094                            }
095                            else {
096                                    return null;
097                            }
098                    }
099                    catch (NoSuchUserException nsue) {
100                            return null;
101                    }
102    
103                    session.setAttribute("j_username", jUsername);
104    
105                    // Not having access to the unencrypted password will not allow you to
106                    // connect to external resources that require it (mail server)
107    
108                    if (encPassword) {
109                            session.setAttribute("j_password", jPassword);
110                    }
111                    else {
112                            session.setAttribute("j_password", PwdEncryptor.encrypt(jPassword));
113    
114                            if (PropsValues.SESSION_STORE_PASSWORD) {
115                                    session.setAttribute(WebKeys.USER_PASSWORD, jPassword);
116                            }
117                    }
118    
119                    session.setAttribute("j_remoteuser", jUsername);
120    
121                    if (PropsValues.PORTAL_JAAS_ENABLE) {
122                            response.sendRedirect(
123                                    PortalUtil.getPathMain() + "/portal/touch_protected");
124                    }
125    
126                    return jUsername;
127            }
128    
129            @Override
130            protected void processFilter(
131                            HttpServletRequest request, HttpServletResponse response,
132                            FilterChain filterChain)
133                    throws Exception {
134    
135                    HttpSession session = request.getSession();
136    
137                    String host = PortalUtil.getHost(request);
138    
139                    if (PortalInstances.isAutoLoginIgnoreHost(host)) {
140                            if (_log.isDebugEnabled()) {
141                                    _log.debug("Ignore host " + host);
142                            }
143    
144                            processFilter(
145                                    AutoLoginFilter.class, request, response, filterChain);
146    
147                            return;
148                    }
149    
150                    String contextPath = PortalUtil.getPathContext();
151    
152                    String path = request.getRequestURI().toLowerCase();
153    
154                    if (!contextPath.equals(StringPool.SLASH) &&
155                            path.contains(contextPath)) {
156    
157                            path = path.substring(contextPath.length());
158                    }
159    
160                    if (PortalInstances.isAutoLoginIgnorePath(path)) {
161                            if (_log.isDebugEnabled()) {
162                                    _log.debug("Ignore path " + path);
163                            }
164    
165                            processFilter(
166                                    AutoLoginFilter.class, request, response, filterChain);
167    
168                            return;
169                    }
170    
171                    String remoteUser = request.getRemoteUser();
172                    String jUserName = (String)session.getAttribute("j_username");
173    
174                    // PLACEHOLDER 01
175                    // PLACEHOLDER 02
176                    // PLACEHOLDER 03
177                    // PLACEHOLDER 04
178                    // PLACEHOLDER 05
179    
180                    if (!PropsValues.AUTH_LOGIN_DISABLED &&
181                            (remoteUser == null) && (jUserName == null)) {
182    
183                            for (AutoLogin autoLogin : _autoLogins) {
184                                    try {
185                                            String[] credentials = autoLogin.login(request, response);
186    
187                                            String redirect = (String)request.getAttribute(
188                                                    AutoLogin.AUTO_LOGIN_REDIRECT);
189    
190                                            if (Validator.isNotNull(redirect)) {
191                                                    response.sendRedirect(redirect);
192    
193                                                    return;
194                                            }
195    
196                                            String loginRemoteUser = getLoginRemoteUser(
197                                                    request, response, session, credentials);
198    
199                                            if (loginRemoteUser != null) {
200                                                    request = new ProtectedServletRequest(
201                                                            request, loginRemoteUser);
202    
203                                                    if (PropsValues.PORTAL_JAAS_ENABLE) {
204                                                            return;
205                                                    }
206    
207                                                    if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
208                                                            redirect = Portal.PATH_MAIN;
209                                                    }
210                                                    else {
211                                                            redirect = (String)request.getAttribute(
212                                                                    AutoLogin.AUTO_LOGIN_REDIRECT_AND_CONTINUE);
213                                                    }
214    
215                                                    if (Validator.isNotNull(redirect)) {
216                                                            response.sendRedirect(redirect);
217    
218                                                            return;
219                                                    }
220                                            }
221                                    }
222                                    catch (Exception e) {
223                                            StringBundler sb = new StringBundler(4);
224    
225                                            sb.append("Current URL ");
226    
227                                            String currentURL = PortalUtil.getCurrentURL(request);
228    
229                                            sb.append(currentURL);
230    
231                                            sb.append(" generates exception: ");
232                                            sb.append(e.getMessage());
233    
234                                            if (currentURL.endsWith(_PATH_CHAT_LATEST)) {
235                                                    if (_log.isWarnEnabled()) {
236                                                            _log.warn(sb.toString());
237                                                    }
238                                            }
239                                            else {
240                                                    _log.error(sb.toString());
241                                            }
242                                    }
243                            }
244                    }
245    
246                    processFilter(AutoLoginFilter.class, request, response, filterChain);
247            }
248    
249            private static final String _PATH_CHAT_LATEST = "/-/chat/latest";
250    
251            private static Log _log = LogFactoryUtil.getLog(AutoLoginFilter.class);
252    
253            private static List<AutoLogin> _autoLogins =
254                    new CopyOnWriteArrayList<AutoLogin>();
255    
256    }