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