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    import com.liferay.portlet.login.util.LoginUtil;
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                    long userId = GetterUtil.getLong(jUsername);
086    
087                    if (userId <= 0) {
088                            return null;
089                    }
090    
091                    User user = UserLocalServiceUtil.fetchUserById(userId);
092    
093                    if ((user == null) || user.isLockout()) {
094                            return null;
095                    }
096    
097                    if (PropsValues.SESSION_ENABLE_PHISHING_PROTECTION) {
098                            session = LoginUtil.renewSession(request, session);
099                    }
100    
101                    session.setAttribute("j_username", jUsername);
102    
103                    // Not having access to the unencrypted password will not allow you to
104                    // connect to external resources that require it (mail server)
105    
106                    if (encPassword) {
107                            session.setAttribute("j_password", jPassword);
108                    }
109                    else {
110                            session.setAttribute(
111                                    "j_password", PasswordEncryptorUtil.encrypt(jPassword));
112    
113                            if (PropsValues.SESSION_STORE_PASSWORD) {
114                                    session.setAttribute(WebKeys.USER_PASSWORD, jPassword);
115                            }
116                    }
117    
118                    session.setAttribute("j_remoteuser", jUsername);
119    
120                    if (PropsValues.PORTAL_JAAS_ENABLE) {
121                            response.sendRedirect(
122                                    PortalUtil.getPathMain() + "/portal/touch_protected");
123                    }
124    
125                    return jUsername;
126            }
127    
128            @Override
129            protected void processFilter(
130                            HttpServletRequest request, HttpServletResponse response,
131                            FilterChain filterChain)
132                    throws Exception {
133    
134                    HttpSession session = request.getSession();
135    
136                    String host = PortalUtil.getHost(request);
137    
138                    if (PortalInstances.isAutoLoginIgnoreHost(host)) {
139                            if (_log.isDebugEnabled()) {
140                                    _log.debug("Ignore host " + host);
141                            }
142    
143                            processFilter(
144                                    AutoLoginFilter.class, request, response, filterChain);
145    
146                            return;
147                    }
148    
149                    String contextPath = PortalUtil.getPathContext();
150    
151                    String path = request.getRequestURI().toLowerCase();
152    
153                    if (!contextPath.equals(StringPool.SLASH) &&
154                            path.contains(contextPath)) {
155    
156                            path = path.substring(contextPath.length());
157                    }
158    
159                    if (PortalInstances.isAutoLoginIgnorePath(path)) {
160                            if (_log.isDebugEnabled()) {
161                                    _log.debug("Ignore path " + path);
162                            }
163    
164                            processFilter(
165                                    AutoLoginFilter.class, request, response, filterChain);
166    
167                            return;
168                    }
169    
170                    String remoteUser = request.getRemoteUser();
171                    String jUserName = (String)session.getAttribute("j_username");
172    
173                    // PLACEHOLDER 01
174                    // PLACEHOLDER 02
175                    // PLACEHOLDER 03
176                    // PLACEHOLDER 04
177                    // PLACEHOLDER 05
178    
179                    if (!PropsValues.AUTH_LOGIN_DISABLED &&
180                            (remoteUser == null) && (jUserName == null)) {
181    
182                            for (AutoLogin autoLogin : _autoLogins) {
183                                    try {
184                                            String[] credentials = autoLogin.login(request, response);
185    
186                                            String redirect = (String)request.getAttribute(
187                                                    AutoLogin.AUTO_LOGIN_REDIRECT);
188    
189                                            if (Validator.isNotNull(redirect)) {
190                                                    response.sendRedirect(redirect);
191    
192                                                    return;
193                                            }
194    
195                                            String loginRemoteUser = getLoginRemoteUser(
196                                                    request, response, session, credentials);
197    
198                                            if (loginRemoteUser != null) {
199                                                    request = new ProtectedServletRequest(
200                                                            request, loginRemoteUser);
201    
202                                                    if (PropsValues.PORTAL_JAAS_ENABLE) {
203                                                            return;
204                                                    }
205    
206                                                    if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
207                                                            redirect = Portal.PATH_MAIN;
208                                                    }
209                                                    else {
210                                                            redirect = (String)request.getAttribute(
211                                                                    AutoLogin.AUTO_LOGIN_REDIRECT_AND_CONTINUE);
212                                                    }
213    
214                                                    if (Validator.isNotNull(redirect)) {
215                                                            response.sendRedirect(redirect);
216    
217                                                            return;
218                                                    }
219                                            }
220                                    }
221                                    catch (Exception e) {
222                                            StringBundler sb = new StringBundler(4);
223    
224                                            sb.append("Current URL ");
225    
226                                            String currentURL = PortalUtil.getCurrentURL(request);
227    
228                                            sb.append(currentURL);
229    
230                                            sb.append(" generates exception: ");
231                                            sb.append(e.getMessage());
232    
233                                            if (currentURL.endsWith(_PATH_CHAT_LATEST)) {
234                                                    if (_log.isWarnEnabled()) {
235                                                            _log.warn(sb.toString());
236                                                    }
237                                            }
238                                            else {
239                                                    _log.error(sb.toString());
240                                            }
241                                    }
242                            }
243                    }
244    
245                    processFilter(AutoLoginFilter.class, request, response, filterChain);
246            }
247    
248            private static final String _PATH_CHAT_LATEST = "/-/chat/latest";
249    
250            private static Log _log = LogFactoryUtil.getLog(AutoLoginFilter.class);
251    
252            private static List<AutoLogin> _autoLogins =
253                    new CopyOnWriteArrayList<AutoLogin>();
254    
255    }