1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.servlet.filters.autologin;
24  
25  import com.liferay.portal.NoSuchUserException;
26  import com.liferay.portal.kernel.log.Log;
27  import com.liferay.portal.kernel.log.LogFactoryUtil;
28  import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
29  import com.liferay.portal.kernel.util.GetterUtil;
30  import com.liferay.portal.kernel.util.InstancePool;
31  import com.liferay.portal.kernel.util.ListUtil;
32  import com.liferay.portal.kernel.util.StringPool;
33  import com.liferay.portal.kernel.util.Validator;
34  import com.liferay.portal.model.User;
35  import com.liferay.portal.security.auth.AutoLogin;
36  import com.liferay.portal.security.pwd.PwdEncryptor;
37  import com.liferay.portal.service.UserLocalServiceUtil;
38  import com.liferay.portal.servlet.filters.BasePortalFilter;
39  import com.liferay.portal.util.PortalInstances;
40  import com.liferay.portal.util.PortalUtil;
41  import com.liferay.portal.util.PropsValues;
42  import com.liferay.portal.util.WebKeys;
43  
44  import java.io.IOException;
45  
46  import java.util.ArrayList;
47  import java.util.List;
48  
49  import javax.servlet.FilterChain;
50  import javax.servlet.ServletException;
51  import javax.servlet.http.HttpServletRequest;
52  import javax.servlet.http.HttpServletResponse;
53  import javax.servlet.http.HttpSession;
54  
55  /**
56   * <a href="AutoLoginFilter.java.html"><b><i>View Source</i></b></a>
57   *
58   * @author Brian Wing Shun Chan
59   * @author Raymond Augé
60   *
61   */
62  public class AutoLoginFilter extends BasePortalFilter {
63  
64      public static void registerAutoLogin(AutoLogin autoLogin) {
65          if (_autoLogins == null) {
66              _log.error("AutoLoginFilter is not initialized yet");
67  
68              return;
69          }
70  
71          List<AutoLogin> autoLogins = ListUtil.fromArray(_autoLogins);
72  
73          autoLogins.add(autoLogin);
74  
75          _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
76      }
77  
78      public static void unregisterAutoLogin(AutoLogin autoLogin) {
79          if (_autoLogins == null) {
80              _log.error("AutoLoginFilter is not initialized yet");
81  
82              return;
83          }
84  
85          List<AutoLogin> autoLogins = ListUtil.fromArray(_autoLogins);
86  
87          if (autoLogins.remove(autoLogin)) {
88              _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
89          }
90      }
91  
92      public AutoLoginFilter() {
93          List<AutoLogin> autoLogins = new ArrayList<AutoLogin>();
94  
95          for (String autoLoginHook : PropsValues.AUTO_LOGIN_HOOKS) {
96              AutoLogin autoLogin = (AutoLogin)InstancePool.get(
97                  autoLoginHook);
98  
99              autoLogins.add(autoLogin);
100         }
101 
102         _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
103     }
104 
105     protected String getLoginRemoteUser(
106             HttpServletRequest request, HttpServletResponse response,
107             HttpSession session, String[] credentials)
108         throws Exception {
109 
110         if ((credentials != null) && (credentials.length == 3)) {
111             String jUsername = credentials[0];
112             String jPassword = credentials[1];
113             boolean encPassword = GetterUtil.getBoolean(credentials[2]);
114 
115             if (Validator.isNotNull(jUsername) &&
116                 Validator.isNotNull(jPassword)) {
117 
118                 try {
119                     long userId = GetterUtil.getLong(jUsername);
120 
121                     if (userId > 0) {
122                         User user = UserLocalServiceUtil.getUserById(userId);
123 
124                         if (user.isLockout()) {
125                             return null;
126                         }
127                     }
128                     else {
129                         return null;
130                     }
131                 }
132                 catch (NoSuchUserException nsue) {
133                     return null;
134                 }
135 
136                 session.setAttribute("j_username", jUsername);
137 
138                 // Not having access to the unencrypted password
139                 // will not allow you to connect to external
140                 // resources that require it (mail server)
141 
142                 if (encPassword) {
143                     session.setAttribute("j_password", jPassword);
144                 }
145                 else {
146                     session.setAttribute(
147                         "j_password", PwdEncryptor.encrypt(jPassword));
148 
149                     session.setAttribute(WebKeys.USER_PASSWORD, jPassword);
150                 }
151 
152                 if (PropsValues.PORTAL_JAAS_ENABLE) {
153                     response.sendRedirect(
154                         PortalUtil.getPathMain() + "/portal/touch_protected");
155                 }
156 
157                 return jUsername;
158             }
159         }
160 
161         return null;
162     }
163 
164     protected void processFilter(
165             HttpServletRequest request, HttpServletResponse response,
166             FilterChain filterChain)
167         throws IOException, ServletException {
168 
169         HttpSession session = request.getSession();
170 
171         String host = PortalUtil.getHost(request);
172 
173         if (PortalInstances.isAutoLoginIgnoreHost(host)) {
174             if (_log.isDebugEnabled()) {
175                 _log.debug("Ignore host " + host);
176             }
177 
178             processFilter(
179                 AutoLoginFilter.class, request, response, filterChain);
180 
181             return;
182         }
183 
184         String contextPath = PortalUtil.getPathContext();
185 
186         String path = request.getRequestURI().toLowerCase();
187 
188         if ((!contextPath.equals(StringPool.SLASH)) &&
189             (path.indexOf(contextPath) != -1)) {
190 
191             path = path.substring(contextPath.length(), path.length());
192         }
193 
194         if (PortalInstances.isAutoLoginIgnorePath(path)) {
195             if (_log.isDebugEnabled()) {
196                 _log.debug("Ignore path " + path);
197             }
198 
199             processFilter(
200                 AutoLoginFilter.class, request, response, filterChain);
201 
202             return;
203         }
204 
205         String remoteUser = request.getRemoteUser();
206         String jUserName = (String)session.getAttribute("j_username");
207 
208         if ((remoteUser == null) && (jUserName == null)) {
209             for (AutoLogin autoLogin : _autoLogins) {
210                 try {
211                     String[] credentials = autoLogin.login(request, response);
212 
213                     String redirect = (String)request.getAttribute(
214                         AutoLogin.AUTO_LOGIN_REDIRECT);
215 
216                     if (redirect != null) {
217                         response.sendRedirect(redirect);
218 
219                         return;
220                     }
221 
222                     String loginRemoteUser = getLoginRemoteUser(
223                         request, response, session, credentials);
224 
225                     if (loginRemoteUser != null) {
226                         request = new ProtectedServletRequest(
227                             request, loginRemoteUser);
228 
229                         if (PropsValues.PORTAL_JAAS_ENABLE) {
230                             return;
231                         }
232                     }
233                 }
234                 catch (Exception e) {
235                     if (_log.isWarnEnabled()) {
236                         _log.warn(e, e);
237                     }
238 
239                     _log.error(e.getMessage());
240                 }
241             }
242         }
243 
244         processFilter(AutoLoginFilter.class, request, response, filterChain);
245     }
246 
247     private static Log _log = LogFactoryUtil.getLog(AutoLoginFilter.class);
248 
249     private static AutoLogin[] _autoLogins;
250 
251 }