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.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.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                    try {
085                            long userId = GetterUtil.getLong(jUsername);
086    
087                            if (userId > 0) {
088                                    User user = UserLocalServiceUtil.getUserById(userId);
089    
090                                    if (user.isLockout()) {
091                                            return null;
092                                    }
093                            }
094                            else {
095                                    return null;
096                            }
097                    }
098                    catch (NoSuchUserException nsue) {
099                            return null;
100                    }
101    
102                    session.setAttribute("j_username", jUsername);
103    
104                    // Not having access to the unencrypted password will not allow you to
105                    // connect to external resources that require it (mail server)
106    
107                    if (encPassword) {
108                            session.setAttribute("j_password", jPassword);
109                    }
110                    else {
111                            session.setAttribute("j_password", PwdEncryptor.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                    if (!PropsValues.AUTH_LOGIN_DISABLED &&
174                            (remoteUser == null) && (jUserName == null)) {
175    
176                            for (AutoLogin autoLogin : _autoLogins) {
177                                    try {
178                                            String[] credentials = autoLogin.login(request, response);
179    
180                                            String redirect = (String)request.getAttribute(
181                                                    AutoLogin.AUTO_LOGIN_REDIRECT);
182    
183                                            if (Validator.isNotNull(redirect)) {
184                                                    response.sendRedirect(redirect);
185    
186                                                    return;
187                                            }
188    
189                                            String loginRemoteUser = getLoginRemoteUser(
190                                                    request, response, session, credentials);
191    
192                                            if (loginRemoteUser != null) {
193                                                    request = new ProtectedServletRequest(
194                                                            request, loginRemoteUser);
195    
196                                                    if (PropsValues.PORTAL_JAAS_ENABLE) {
197                                                            return;
198                                                    }
199    
200                                                    if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
201                                                            redirect = Portal.PATH_MAIN;
202                                                    }
203                                                    else {
204                                                            redirect = (String)request.getAttribute(
205                                                                    AutoLogin.AUTO_LOGIN_REDIRECT_AND_CONTINUE);
206                                                    }
207    
208                                                    if (Validator.isNotNull(redirect)) {
209                                                            response.sendRedirect(redirect);
210    
211                                                            return;
212                                                    }
213                                            }
214                                    }
215                                    catch (Exception e) {
216                                            if (_log.isWarnEnabled()) {
217                                                    _log.warn(e, e);
218                                            }
219    
220                                            String currentURL = PortalUtil.getCurrentURL(request);
221    
222                                            if (currentURL.endsWith(_PATH_CHAT_LATEST)) {
223                                                    if (_log.isWarnEnabled()) {
224                                                            _log.warn(
225                                                                    "Current URL " + currentURL +
226                                                                            " generates exception: " + e.getMessage());
227                                                    }
228                                            }
229                                            else {
230                                                    _log.error(
231                                                            "Current URL " + currentURL +
232                                                                    " generates exception: " + e.getMessage());
233                                            }
234                                    }
235                            }
236                    }
237    
238                    processFilter(AutoLoginFilter.class, request, response, filterChain);
239            }
240    
241            private static final String _PATH_CHAT_LATEST = "/-/chat/latest";
242    
243            private static Log _log = LogFactoryUtil.getLog(AutoLoginFilter.class);
244    
245            private static List<AutoLogin> _autoLogins =
246                    new CopyOnWriteArrayList<AutoLogin>();
247    
248    }