001    /**
002     * Copyright (c) 2000-2013 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.PasswordEncryptorUtil;
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(
113                                    "j_password", PasswordEncryptorUtil.encrypt(jPassword));
114    
115                            if (PropsValues.SESSION_STORE_PASSWORD) {
116                                    session.setAttribute(WebKeys.USER_PASSWORD, jPassword);
117                            }
118                    }
119    
120                    session.setAttribute("j_remoteuser", jUsername);
121    
122                    if (PropsValues.PORTAL_JAAS_ENABLE) {
123                            response.sendRedirect(
124                                    PortalUtil.getPathMain() + "/portal/touch_protected");
125                    }
126    
127                    return jUsername;
128            }
129    
130            @Override
131            protected void processFilter(
132                            HttpServletRequest request, HttpServletResponse response,
133                            FilterChain filterChain)
134                    throws Exception {
135    
136                    HttpSession session = request.getSession();
137    
138                    String host = PortalUtil.getHost(request);
139    
140                    if (PortalInstances.isAutoLoginIgnoreHost(host)) {
141                            if (_log.isDebugEnabled()) {
142                                    _log.debug("Ignore host " + host);
143                            }
144    
145                            processFilter(
146                                    AutoLoginFilter.class, request, response, filterChain);
147    
148                            return;
149                    }
150    
151                    String contextPath = PortalUtil.getPathContext();
152    
153                    String path = request.getRequestURI().toLowerCase();
154    
155                    if (!contextPath.equals(StringPool.SLASH) &&
156                            path.contains(contextPath)) {
157    
158                            path = path.substring(contextPath.length());
159                    }
160    
161                    if (PortalInstances.isAutoLoginIgnorePath(path)) {
162                            if (_log.isDebugEnabled()) {
163                                    _log.debug("Ignore path " + path);
164                            }
165    
166                            processFilter(
167                                    AutoLoginFilter.class, request, response, filterChain);
168    
169                            return;
170                    }
171    
172                    String remoteUser = request.getRemoteUser();
173                    String jUserName = (String)session.getAttribute("j_username");
174    
175                    // PLACEHOLDER 01
176                    // PLACEHOLDER 02
177                    // PLACEHOLDER 03
178                    // PLACEHOLDER 04
179                    // PLACEHOLDER 05
180    
181                    if (!PropsValues.AUTH_LOGIN_DISABLED &&
182                            (remoteUser == null) && (jUserName == null)) {
183    
184                            for (AutoLogin autoLogin : _autoLogins) {
185                                    try {
186                                            String[] credentials = autoLogin.login(request, response);
187    
188                                            String redirect = (String)request.getAttribute(
189                                                    AutoLogin.AUTO_LOGIN_REDIRECT);
190    
191                                            if (Validator.isNotNull(redirect)) {
192                                                    response.sendRedirect(redirect);
193    
194                                                    return;
195                                            }
196    
197                                            String loginRemoteUser = getLoginRemoteUser(
198                                                    request, response, session, credentials);
199    
200                                            if (loginRemoteUser != null) {
201                                                    request = new ProtectedServletRequest(
202                                                            request, loginRemoteUser);
203    
204                                                    if (PropsValues.PORTAL_JAAS_ENABLE) {
205                                                            return;
206                                                    }
207    
208                                                    if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
209                                                            redirect = Portal.PATH_MAIN;
210                                                    }
211                                                    else {
212                                                            redirect = (String)request.getAttribute(
213                                                                    AutoLogin.AUTO_LOGIN_REDIRECT_AND_CONTINUE);
214                                                    }
215    
216                                                    if (Validator.isNotNull(redirect)) {
217                                                            response.sendRedirect(redirect);
218    
219                                                            return;
220                                                    }
221                                            }
222                                    }
223                                    catch (Exception e) {
224                                            StringBundler sb = new StringBundler(4);
225    
226                                            sb.append("Current URL ");
227    
228                                            String currentURL = PortalUtil.getCurrentURL(request);
229    
230                                            sb.append(currentURL);
231    
232                                            sb.append(" generates exception: ");
233                                            sb.append(e.getMessage());
234    
235                                            if (currentURL.endsWith(_PATH_CHAT_LATEST)) {
236                                                    if (_log.isWarnEnabled()) {
237                                                            _log.warn(sb.toString());
238                                                    }
239                                            }
240                                            else {
241                                                    _log.error(sb.toString());
242                                            }
243                                    }
244                            }
245                    }
246    
247                    processFilter(AutoLoginFilter.class, request, response, filterChain);
248            }
249    
250            private static final String _PATH_CHAT_LATEST = "/-/chat/latest";
251    
252            private static Log _log = LogFactoryUtil.getLog(AutoLoginFilter.class);
253    
254            private static List<AutoLogin> _autoLogins =
255                    new CopyOnWriteArrayList<AutoLogin>();
256    
257    }