001    /**
002     * Copyright (c) 2000-2010 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.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.ListUtil;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.model.User;
027    import com.liferay.portal.security.auth.AutoLogin;
028    import com.liferay.portal.security.pwd.PwdEncryptor;
029    import com.liferay.portal.service.UserLocalServiceUtil;
030    import com.liferay.portal.servlet.filters.BasePortalFilter;
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.ArrayList;
037    import java.util.List;
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                    if (_autoLogins == null) {
052                            _log.error("AutoLoginFilter is not initialized yet");
053    
054                            return;
055                    }
056    
057                    List<AutoLogin> autoLogins = ListUtil.fromArray(_autoLogins);
058    
059                    autoLogins.add(autoLogin);
060    
061                    _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
062            }
063    
064            public static void unregisterAutoLogin(AutoLogin autoLogin) {
065                    if (_autoLogins == null) {
066                            _log.error("AutoLoginFilter is not initialized yet");
067    
068                            return;
069                    }
070    
071                    List<AutoLogin> autoLogins = ListUtil.fromArray(_autoLogins);
072    
073                    if (autoLogins.remove(autoLogin)) {
074                            _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
075                    }
076            }
077    
078            public AutoLoginFilter() {
079                    List<AutoLogin> autoLogins = new ArrayList<AutoLogin>();
080    
081                    for (String autoLoginClassName : PropsValues.AUTO_LOGIN_HOOKS) {
082                            AutoLogin autoLogin = (AutoLogin)InstancePool.get(
083                                    autoLoginClassName);
084    
085                            autoLogins.add(autoLogin);
086                    }
087    
088                    _autoLogins = autoLogins.toArray(new AutoLogin[autoLogins.size()]);
089            }
090    
091            protected String getLoginRemoteUser(
092                            HttpServletRequest request, HttpServletResponse response,
093                            HttpSession session, String[] credentials)
094                    throws Exception {
095    
096                    if ((credentials != null) && (credentials.length == 3)) {
097                            String jUsername = credentials[0];
098                            String jPassword = credentials[1];
099                            boolean encPassword = GetterUtil.getBoolean(credentials[2]);
100    
101                            if (Validator.isNotNull(jUsername) &&
102                                    Validator.isNotNull(jPassword)) {
103    
104                                    try {
105                                            long userId = GetterUtil.getLong(jUsername);
106    
107                                            if (userId > 0) {
108                                                    User user = UserLocalServiceUtil.getUserById(userId);
109    
110                                                    if (user.isLockout()) {
111                                                            return null;
112                                                    }
113                                            }
114                                            else {
115                                                    return null;
116                                            }
117                                    }
118                                    catch (NoSuchUserException nsue) {
119                                            return null;
120                                    }
121    
122                                    session.setAttribute("j_username", jUsername);
123    
124                                    // Not having access to the unencrypted password
125                                    // will not allow you to connect to external
126                                    // resources that require it (mail server)
127    
128                                    if (encPassword) {
129                                            session.setAttribute("j_password", jPassword);
130                                    }
131                                    else {
132                                            session.setAttribute(
133                                                    "j_password", PwdEncryptor.encrypt(jPassword));
134    
135                                            if (PropsValues.SESSION_STORE_PASSWORD) {
136                                                    session.setAttribute(WebKeys.USER_PASSWORD, jPassword);
137                                            }
138                                    }
139    
140                                    session.setAttribute("j_remoteuser", jUsername);
141    
142                                    if (PropsValues.PORTAL_JAAS_ENABLE) {
143                                            response.sendRedirect(
144                                                    PortalUtil.getPathMain() + "/portal/touch_protected");
145                                    }
146    
147                                    return jUsername;
148                            }
149                    }
150    
151                    return null;
152            }
153    
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 = request.getRequestURI().toLowerCase();
177    
178                    if ((!contextPath.equals(StringPool.SLASH)) &&
179                            (path.indexOf(contextPath) != -1)) {
180    
181                            path = path.substring(contextPath.length(), path.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                    if ((remoteUser == null) && (jUserName == null)) {
199                            for (AutoLogin autoLogin : _autoLogins) {
200                                    try {
201                                            String[] credentials = autoLogin.login(request, response);
202    
203                                            String redirect = (String)request.getAttribute(
204                                                    AutoLogin.AUTO_LOGIN_REDIRECT);
205    
206                                            if (Validator.isNotNull(redirect)) {
207                                                    response.sendRedirect(redirect);
208    
209                                                    return;
210                                            }
211    
212                                            String loginRemoteUser = getLoginRemoteUser(
213                                                    request, response, session, credentials);
214    
215                                            if (loginRemoteUser != null) {
216                                                    request = new ProtectedServletRequest(
217                                                            request, loginRemoteUser);
218    
219                                                    if (PropsValues.PORTAL_JAAS_ENABLE) {
220                                                            return;
221                                                    }
222    
223                                                    redirect = (String)request.getAttribute(
224                                                            AutoLogin.AUTO_LOGIN_REDIRECT_AND_CONTINUE);
225    
226                                                    if (Validator.isNotNull(redirect)) {
227                                                            response.sendRedirect(redirect);
228    
229                                                            break;
230                                                    }
231                                            }
232                                    }
233                                    catch (Exception e) {
234                                            if (_log.isWarnEnabled()) {
235                                                    _log.warn(e, e);
236                                            }
237    
238                                            String currentURL = PortalUtil.getCurrentURL(request);
239    
240                                            if (currentURL.endsWith(_PATH_CHAT_LATEST)) {
241                                                    if (_log.isWarnEnabled()) {
242                                                            _log.warn(
243                                                                    "Current URL " + currentURL +
244                                                                            " generates exception: " + e.getMessage());
245                                                    }
246                                            }
247                                            else {
248                                                    _log.error(
249                                                            "Current URL " + currentURL +
250                                                                    " generates exception: " + e.getMessage());
251                                            }
252                                    }
253                            }
254                    }
255    
256                    processFilter(AutoLoginFilter.class, request, response, filterChain);
257            }
258    
259            private static final String _PATH_CHAT_LATEST = "/-/chat/latest";
260    
261            private static Log _log = LogFactoryUtil.getLog(AutoLoginFilter.class);
262    
263            private static AutoLogin[] _autoLogins;
264    
265    }