1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
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.StringPool;
24  import com.liferay.portal.kernel.util.Validator;
25  import com.liferay.portal.model.User;
26  import com.liferay.portal.security.auth.AutoLogin;
27  import com.liferay.portal.security.pwd.PwdEncryptor;
28  import com.liferay.portal.service.UserLocalServiceUtil;
29  import com.liferay.portal.servlet.filters.BasePortalFilter;
30  import com.liferay.portal.util.PortalInstances;
31  import com.liferay.portal.util.PortalUtil;
32  import com.liferay.portal.util.PropsValues;
33  import com.liferay.portal.util.WebKeys;
34  
35  import java.util.List;
36  import java.util.concurrent.CopyOnWriteArrayList;
37  
38  import javax.servlet.FilterChain;
39  import javax.servlet.http.HttpServletRequest;
40  import javax.servlet.http.HttpServletResponse;
41  import javax.servlet.http.HttpSession;
42  
43  /**
44   * <a href="AutoLoginFilter.java.html"><b><i>View Source</i></b></a>
45   *
46   * @author Brian Wing Shun Chan
47   * @author Raymond Augé
48   */
49  public class AutoLoginFilter extends BasePortalFilter {
50  
51      public static void registerAutoLogin(AutoLogin autoLogin) {
52          if (_autoLogins == null) {
53              _log.error("AutoLoginFilter is not initialized yet");
54  
55              return;
56          }
57  
58          _autoLogins.add(autoLogin);
59      }
60  
61      public static void unregisterAutoLogin(AutoLogin autoLogin) {
62          if (_autoLogins == null) {
63              _log.error("AutoLoginFilter is not initialized yet");
64  
65              return;
66          }
67  
68          _autoLogins.remove(autoLogin);
69      }
70  
71      public AutoLoginFilter() {
72          _autoLogins = new CopyOnWriteArrayList<AutoLogin>();
73  
74          for (String autoLoginClassName : PropsValues.AUTO_LOGIN_HOOKS) {
75              AutoLogin autoLogin = (AutoLogin)InstancePool.get(
76                  autoLoginClassName);
77  
78              _autoLogins.add(autoLogin);
79          }
80      }
81  
82      protected String getLoginRemoteUser(
83              HttpServletRequest request, HttpServletResponse response,
84              HttpSession session, String[] credentials)
85          throws Exception {
86  
87          if ((credentials != null) && (credentials.length == 3)) {
88              String jUsername = credentials[0];
89              String jPassword = credentials[1];
90              boolean encPassword = GetterUtil.getBoolean(credentials[2]);
91  
92              if (Validator.isNotNull(jUsername) &&
93                  Validator.isNotNull(jPassword)) {
94  
95                  try {
96                      long userId = GetterUtil.getLong(jUsername);
97  
98                      if (userId > 0) {
99                          User user = UserLocalServiceUtil.getUserById(userId);
100 
101                         if (user.isLockout()) {
102                             return null;
103                         }
104                     }
105                     else {
106                         return null;
107                     }
108                 }
109                 catch (NoSuchUserException nsue) {
110                     return null;
111                 }
112 
113                 session.setAttribute("j_username", jUsername);
114 
115                 // Not having access to the unencrypted password
116                 // will not allow you to connect to external
117                 // resources that require it (mail server)
118 
119                 if (encPassword) {
120                     session.setAttribute("j_password", jPassword);
121                 }
122                 else {
123                     session.setAttribute(
124                         "j_password", PwdEncryptor.encrypt(jPassword));
125 
126                     session.setAttribute(WebKeys.USER_PASSWORD, jPassword);
127                 }
128 
129                 session.setAttribute("j_remoteuser", jUsername);
130 
131                 if (PropsValues.PORTAL_JAAS_ENABLE) {
132                     response.sendRedirect(
133                         PortalUtil.getPathMain() + "/portal/touch_protected");
134                 }
135 
136                 return jUsername;
137             }
138         }
139 
140         return null;
141     }
142 
143     protected void processFilter(
144             HttpServletRequest request, HttpServletResponse response,
145             FilterChain filterChain)
146         throws Exception {
147 
148         HttpSession session = request.getSession();
149 
150         String host = PortalUtil.getHost(request);
151 
152         if (PortalInstances.isAutoLoginIgnoreHost(host)) {
153             if (_log.isDebugEnabled()) {
154                 _log.debug("Ignore host " + host);
155             }
156 
157             processFilter(
158                 AutoLoginFilter.class, request, response, filterChain);
159 
160             return;
161         }
162 
163         String contextPath = PortalUtil.getPathContext();
164 
165         String path = request.getRequestURI().toLowerCase();
166 
167         if ((!contextPath.equals(StringPool.SLASH)) &&
168             (path.indexOf(contextPath) != -1)) {
169 
170             path = path.substring(contextPath.length(), path.length());
171         }
172 
173         if (PortalInstances.isAutoLoginIgnorePath(path)) {
174             if (_log.isDebugEnabled()) {
175                 _log.debug("Ignore path " + path);
176             }
177 
178             processFilter(
179                 AutoLoginFilter.class, request, response, filterChain);
180 
181             return;
182         }
183 
184         String remoteUser = request.getRemoteUser();
185         String jUserName = (String)session.getAttribute("j_username");
186 
187         if ((remoteUser == null) && (jUserName == null)) {
188             for (AutoLogin autoLogin : _autoLogins) {
189                 try {
190                     String[] credentials = autoLogin.login(request, response);
191 
192                     String redirect = (String)request.getAttribute(
193                         AutoLogin.AUTO_LOGIN_REDIRECT);
194 
195                     if (Validator.isNotNull(redirect)) {
196                         response.sendRedirect(redirect);
197 
198                         return;
199                     }
200 
201                     String loginRemoteUser = getLoginRemoteUser(
202                         request, response, session, credentials);
203 
204                     if (loginRemoteUser != null) {
205                         request = new ProtectedServletRequest(
206                             request, loginRemoteUser);
207 
208                         if (PropsValues.PORTAL_JAAS_ENABLE) {
209                             return;
210                         }
211 
212                         redirect = (String)request.getAttribute(
213                             AutoLogin.AUTO_LOGIN_REDIRECT_AND_CONTINUE);
214 
215                         if (Validator.isNotNull(redirect)) {
216                             response.sendRedirect(redirect);
217 
218                             break;
219                         }
220                     }
221                 }
222                 catch (Exception e) {
223                     if (_log.isWarnEnabled()) {
224                         _log.warn(e, e);
225                     }
226 
227                     String currentURL = PortalUtil.getCurrentURL(request);
228 
229                     if (currentURL.endsWith(_PATH_CHAT_LATEST)) {
230                         if (_log.isWarnEnabled()) {
231                             _log.warn(
232                                 "Current URL " + currentURL +
233                                     " generates exception: " + e.getMessage());
234                         }
235                     }
236                     else {
237                         _log.error(
238                             "Current URL " + currentURL +
239                                 " generates exception: " + e.getMessage());
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 
254 }