1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.servlet.filters.autologin;
16  
17  import com.liferay.portal.NoSuchUserException;
18  import com.liferay.portal.kernel.log.Log;
19  import com.liferay.portal.kernel.log.LogFactoryUtil;
20  import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
21  import com.liferay.portal.kernel.util.GetterUtil;
22  import com.liferay.portal.kernel.util.InstancePool;
23  import com.liferay.portal.kernel.util.ListUtil;
24  import com.liferay.portal.kernel.util.StringPool;
25  import com.liferay.portal.kernel.util.Validator;
26  import com.liferay.portal.model.User;
27  import com.liferay.portal.security.auth.AutoLogin;
28  import com.liferay.portal.security.pwd.PwdEncryptor;
29  import com.liferay.portal.service.UserLocalServiceUtil;
30  import com.liferay.portal.servlet.filters.BasePortalFilter;
31  import com.liferay.portal.util.PortalInstances;
32  import com.liferay.portal.util.PortalUtil;
33  import com.liferay.portal.util.PropsValues;
34  import com.liferay.portal.util.WebKeys;
35  
36  import java.util.ArrayList;
37  import java.util.List;
38  
39  import javax.servlet.FilterChain;
40  import javax.servlet.http.HttpServletRequest;
41  import javax.servlet.http.HttpServletResponse;
42  import javax.servlet.http.HttpSession;
43  
44  /**
45   * <a href="AutoLoginFilter.java.html"><b><i>View Source</i></b></a>
46   *
47   * @author Brian Wing Shun Chan
48   * @author Raymond Augé
49   */
50  public class AutoLoginFilter extends BasePortalFilter {
51  
52      public static void registerAutoLogin(AutoLogin autoLogin) {
53          if (_autoLogins == null) {
54              _log.error("AutoLoginFilter is not initialized yet");
55  
56              return;
57          }
58  
59          List<AutoLogin> autoLogins = ListUtil.fromArray(_autoLogins);
60  
61          autoLogins.add(autoLogin);
62  
63          _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
64      }
65  
66      public static void unregisterAutoLogin(AutoLogin autoLogin) {
67          if (_autoLogins == null) {
68              _log.error("AutoLoginFilter is not initialized yet");
69  
70              return;
71          }
72  
73          List<AutoLogin> autoLogins = ListUtil.fromArray(_autoLogins);
74  
75          if (autoLogins.remove(autoLogin)) {
76              _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
77          }
78      }
79  
80      public AutoLoginFilter() {
81          List<AutoLogin> autoLogins = new ArrayList<AutoLogin>();
82  
83          for (String autoLoginClassName : PropsValues.AUTO_LOGIN_HOOKS) {
84              AutoLogin autoLogin = (AutoLogin)InstancePool.get(
85                  autoLoginClassName);
86  
87              autoLogins.add(autoLogin);
88          }
89  
90          _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
91      }
92  
93      protected String getLoginRemoteUser(
94              HttpServletRequest request, HttpServletResponse response,
95              HttpSession session, String[] credentials)
96          throws Exception {
97  
98          if ((credentials != null) && (credentials.length == 3)) {
99              String jUsername = credentials[0];
100             String jPassword = credentials[1];
101             boolean encPassword = GetterUtil.getBoolean(credentials[2]);
102 
103             if (Validator.isNotNull(jUsername) &&
104                 Validator.isNotNull(jPassword)) {
105 
106                 try {
107                     long userId = GetterUtil.getLong(jUsername);
108 
109                     if (userId > 0) {
110                         User user = UserLocalServiceUtil.getUserById(userId);
111 
112                         if (user.isLockout()) {
113                             return null;
114                         }
115                     }
116                     else {
117                         return null;
118                     }
119                 }
120                 catch (NoSuchUserException nsue) {
121                     return null;
122                 }
123 
124                 session.setAttribute("j_username", jUsername);
125 
126                 // Not having access to the unencrypted password
127                 // will not allow you to connect to external
128                 // resources that require it (mail server)
129 
130                 if (encPassword) {
131                     session.setAttribute("j_password", jPassword);
132                 }
133                 else {
134                     session.setAttribute(
135                         "j_password", PwdEncryptor.encrypt(jPassword));
136 
137                     session.setAttribute(WebKeys.USER_PASSWORD, jPassword);
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 }