001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.HttpUtil;
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.StringUtil;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.model.User;
028    import com.liferay.portal.security.auth.AutoLogin;
029    import com.liferay.portal.security.pwd.PasswordEncryptorUtil;
030    import com.liferay.portal.service.UserLocalServiceUtil;
031    import com.liferay.portal.servlet.filters.BasePortalFilter;
032    import com.liferay.portal.util.Portal;
033    import com.liferay.portal.util.PortalInstances;
034    import com.liferay.portal.util.PortalUtil;
035    import com.liferay.portal.util.PropsValues;
036    import com.liferay.portal.util.WebKeys;
037    import com.liferay.portlet.login.util.LoginUtil;
038    
039    import java.util.List;
040    import java.util.concurrent.CopyOnWriteArrayList;
041    
042    import javax.servlet.FilterChain;
043    import javax.servlet.http.HttpServletRequest;
044    import javax.servlet.http.HttpServletResponse;
045    import javax.servlet.http.HttpSession;
046    
047    /**
048     * @author Brian Wing Shun Chan
049     * @author Raymond Aug??
050     */
051    public class AutoLoginFilter extends BasePortalFilter {
052    
053            public static void registerAutoLogin(AutoLogin autoLogin) {
054                    _autoLogins.add(autoLogin);
055            }
056    
057            public static void unregisterAutoLogin(AutoLogin autoLogin) {
058                    _autoLogins.remove(autoLogin);
059            }
060    
061            public AutoLoginFilter() {
062                    for (String autoLoginClassName : PropsValues.AUTO_LOGIN_HOOKS) {
063                            AutoLogin autoLogin = (AutoLogin)InstancePool.get(
064                                    autoLoginClassName);
065    
066                            _autoLogins.add(autoLogin);
067                    }
068            }
069    
070            protected String getLoginRemoteUser(
071                            HttpServletRequest request, HttpServletResponse response,
072                            HttpSession session, String[] credentials)
073                    throws Exception {
074    
075                    if ((credentials == null) || (credentials.length != 3)) {
076                            return null;
077                    }
078    
079                    String jUsername = credentials[0];
080                    String jPassword = credentials[1];
081                    boolean encPassword = GetterUtil.getBoolean(credentials[2]);
082    
083                    if (Validator.isNull(jUsername) || Validator.isNull(jPassword)) {
084                            return null;
085                    }
086    
087                    long userId = GetterUtil.getLong(jUsername);
088    
089                    if (userId <= 0) {
090                            return null;
091                    }
092    
093                    User user = UserLocalServiceUtil.fetchUserById(userId);
094    
095                    if ((user == null) || user.isLockout()) {
096                            return null;
097                    }
098    
099                    if (!PropsValues.AUTH_SIMULTANEOUS_LOGINS) {
100                            LoginUtil.signOutSimultaneousLogins(userId);
101                    }
102    
103                    if (PropsValues.SESSION_ENABLE_PHISHING_PROTECTION) {
104                            session = LoginUtil.renewSession(request, session);
105                    }
106    
107                    session.setAttribute("j_username", jUsername);
108    
109                    // Not having access to the unencrypted password will not allow you to
110                    // connect to external resources that require it (mail server)
111    
112                    if (encPassword) {
113                            session.setAttribute("j_password", jPassword);
114                    }
115                    else {
116                            session.setAttribute(
117                                    "j_password",
118                                    PasswordEncryptorUtil.encrypt(jPassword, user.getPassword()));
119    
120                            if (PropsValues.SESSION_STORE_PASSWORD) {
121                                    session.setAttribute(WebKeys.USER_PASSWORD, jPassword);
122                            }
123                    }
124    
125                    session.setAttribute("j_remoteuser", jUsername);
126    
127                    if (PropsValues.PORTAL_JAAS_ENABLE) {
128                            String mainPath = PortalUtil.getPathMain();
129    
130                            String redirect = mainPath.concat("/portal/protected");
131    
132                            if (PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
133                                    redirect = redirect.concat("?redirect=");
134    
135                                    String autoLoginRedirect = (String)request.getAttribute(
136                                            AutoLogin.AUTO_LOGIN_REDIRECT_AND_CONTINUE);
137    
138                                    if (Validator.isNull(autoLoginRedirect)) {
139                                            autoLoginRedirect = PortalUtil.getCurrentCompleteURL(
140                                                    request);
141                                    }
142    
143                                    redirect = redirect.concat(
144                                            HttpUtil.encodeURL(autoLoginRedirect));
145                            }
146    
147                            response.sendRedirect(redirect);
148                    }
149    
150                    return jUsername;
151            }
152    
153            @Override
154            protected void processFilter(
155                            HttpServletRequest request, HttpServletResponse response,
156                            FilterChain filterChain)
157                    throws Exception {
158    
159                    HttpSession session = request.getSession();
160    
161                    String host = PortalUtil.getHost(request);
162    
163                    if (PortalInstances.isAutoLoginIgnoreHost(host)) {
164                            if (_log.isDebugEnabled()) {
165                                    _log.debug("Ignore host " + host);
166                            }
167    
168                            processFilter(
169                                    AutoLoginFilter.class, request, response, filterChain);
170    
171                            return;
172                    }
173    
174                    String contextPath = PortalUtil.getPathContext();
175    
176                    String path = StringUtil.toLowerCase(request.getRequestURI());
177    
178                    if (!contextPath.equals(StringPool.SLASH) &&
179                            path.contains(contextPath)) {
180    
181                            path = path.substring(contextPath.length());
182                    }
183    
184                    if (PortalInstances.isAutoLoginIgnorePath(path)) {
185                            if (_log.isDebugEnabled()) {
186                                    _log.debug("Ignore path " + path);
187                            }
188    
189                            processFilter(
190                                    AutoLoginFilter.class, request, response, filterChain);
191    
192                            return;
193                    }
194    
195                    String remoteUser = request.getRemoteUser();
196                    String jUserName = (String)session.getAttribute("j_username");
197    
198                    // PLACEHOLDER 01
199                    // PLACEHOLDER 02
200                    // PLACEHOLDER 03
201                    // PLACEHOLDER 04
202                    // PLACEHOLDER 05
203    
204                    if (!PropsValues.AUTH_LOGIN_DISABLED &&
205                            (remoteUser == null) && (jUserName == null)) {
206    
207                            for (AutoLogin autoLogin : _autoLogins) {
208                                    try {
209                                            String[] credentials = autoLogin.login(request, response);
210    
211                                            String redirect = (String)request.getAttribute(
212                                                    AutoLogin.AUTO_LOGIN_REDIRECT);
213    
214                                            if (Validator.isNotNull(redirect)) {
215                                                    response.sendRedirect(redirect);
216    
217                                                    return;
218                                            }
219    
220                                            String loginRemoteUser = getLoginRemoteUser(
221                                                    request, response, session, credentials);
222    
223                                            if (loginRemoteUser != null) {
224                                                    request = new ProtectedServletRequest(
225                                                            request, loginRemoteUser);
226    
227                                                    if (PropsValues.PORTAL_JAAS_ENABLE) {
228                                                            return;
229                                                    }
230    
231                                                    if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
232                                                            redirect = Portal.PATH_MAIN;
233                                                    }
234                                                    else {
235                                                            redirect = (String)request.getAttribute(
236                                                                    AutoLogin.AUTO_LOGIN_REDIRECT_AND_CONTINUE);
237                                                    }
238    
239                                                    if (Validator.isNotNull(redirect)) {
240                                                            response.sendRedirect(redirect);
241    
242                                                            return;
243                                                    }
244                                            }
245                                    }
246                                    catch (Exception e) {
247                                            StringBundler sb = new StringBundler(4);
248    
249                                            sb.append("Current URL ");
250    
251                                            String currentURL = PortalUtil.getCurrentURL(request);
252    
253                                            sb.append(currentURL);
254    
255                                            sb.append(" generates exception: ");
256                                            sb.append(e.getMessage());
257    
258                                            if (currentURL.endsWith(_PATH_CHAT_LATEST)) {
259                                                    if (_log.isWarnEnabled()) {
260                                                            _log.warn(sb.toString());
261                                                    }
262                                            }
263                                            else {
264                                                    _log.error(sb.toString());
265                                            }
266                                    }
267                            }
268                    }
269    
270                    processFilter(AutoLoginFilter.class, request, response, filterChain);
271            }
272    
273            private static final String _PATH_CHAT_LATEST = "/-/chat/latest";
274    
275            private static Log _log = LogFactoryUtil.getLog(AutoLoginFilter.class);
276    
277            private static List<AutoLogin> _autoLogins =
278                    new CopyOnWriteArrayList<AutoLogin>();
279    
280    }