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