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