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.security.auth;
16  
17  import com.liferay.portal.kernel.exception.SystemException;
18  import com.liferay.portal.kernel.log.Log;
19  import com.liferay.portal.kernel.log.LogFactoryUtil;
20  import com.liferay.portal.kernel.util.ParamUtil;
21  import com.liferay.portal.kernel.util.PropsKeys;
22  import com.liferay.portal.kernel.util.StringPool;
23  import com.liferay.portal.kernel.util.StringUtil;
24  import com.liferay.portal.kernel.util.Validator;
25  import com.liferay.portal.model.CompanyConstants;
26  import com.liferay.portal.model.User;
27  import com.liferay.portal.security.ldap.LDAPSettingsUtil;
28  import com.liferay.portal.security.ldap.PortalLDAPImporterUtil;
29  import com.liferay.portal.security.ldap.PortalLDAPUtil;
30  import com.liferay.portal.service.UserLocalServiceUtil;
31  import com.liferay.portal.servlet.filters.sso.cas.CASFilter;
32  import com.liferay.portal.util.PortalUtil;
33  import com.liferay.portal.util.PrefsPropsUtil;
34  import com.liferay.portal.util.PropsValues;
35  
36  import javax.naming.Binding;
37  import javax.naming.NamingEnumeration;
38  import javax.naming.directory.Attributes;
39  import javax.naming.directory.SearchControls;
40  import javax.naming.directory.SearchResult;
41  import javax.naming.ldap.LdapContext;
42  
43  import javax.servlet.http.HttpServletRequest;
44  import javax.servlet.http.HttpServletResponse;
45  import javax.servlet.http.HttpSession;
46  
47  /**
48   * <a href="CASAutoLogin.java.html"><b><i>View Source</i></b></a>
49   *
50   * @author Brian Wing Shun Chan
51   * @author Jorge Ferrer
52   * @author Wesley Gong
53   * @author Daeyoung Song
54   */
55  public class CASAutoLogin implements AutoLogin {
56  
57      public String[] login(
58          HttpServletRequest request, HttpServletResponse response) {
59  
60          String[] credentials = null;
61  
62          try {
63              long companyId = PortalUtil.getCompanyId(request);
64  
65              if (!PrefsPropsUtil.getBoolean(
66                      companyId, PropsKeys.CAS_AUTH_ENABLED,
67                      PropsValues.CAS_AUTH_ENABLED)) {
68  
69                  return credentials;
70              }
71  
72              HttpSession session = request.getSession();
73  
74              String login = (String)session.getAttribute(CASFilter.LOGIN);
75  
76              if (Validator.isNull(login)) {
77                  return credentials;
78              }
79  
80              String authType = PrefsPropsUtil.getString(
81                  companyId, PropsKeys.COMPANY_SECURITY_AUTH_TYPE,
82                  PropsValues.COMPANY_SECURITY_AUTH_TYPE);
83  
84              User user = null;
85  
86              if (PrefsPropsUtil.getBoolean(
87                      companyId, PropsKeys.CAS_IMPORT_FROM_LDAP,
88                      PropsValues.CAS_IMPORT_FROM_LDAP)) {
89  
90                  try {
91                      if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
92                          user = importLDAPUser(
93                              companyId, StringPool.BLANK, login);
94                      }
95                      else {
96                          user = importLDAPUser(
97                              companyId, login, StringPool.BLANK);
98                      }
99                  }
100                 catch (SystemException se) {
101                 }
102             }
103 
104             if (user == null) {
105                 if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
106                     user = UserLocalServiceUtil.getUserByScreenName(
107                         companyId, login);
108                 }
109                 else {
110                     user = UserLocalServiceUtil.getUserByEmailAddress(
111                         companyId, login);
112                 }
113             }
114 
115             String redirect = ParamUtil.getString(request, "redirect");
116 
117             if (Validator.isNotNull(redirect)) {
118                 request.setAttribute(AutoLogin.AUTO_LOGIN_REDIRECT, redirect);
119             }
120 
121             credentials = new String[3];
122 
123             credentials[0] = String.valueOf(user.getUserId());
124             credentials[1] = user.getPassword();
125             credentials[2] = Boolean.TRUE.toString();
126 
127             return credentials;
128         }
129         catch (Exception e) {
130             _log.error(e, e);
131         }
132 
133         return credentials;
134     }
135 
136     /**
137      * @deprecated Use <code>importLDAPUser</code>.
138      */
139     protected User addUser(long companyId, String screenName) throws Exception {
140         return importLDAPUser(companyId, StringPool.BLANK, screenName);
141     }
142 
143     protected User importLDAPUser(
144             long ldapServerId, long companyId, String emailAddress,
145             String screenName)
146         throws Exception {
147 
148         LdapContext ctx = null;
149 
150         try {
151             String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
152 
153             String baseDN = PrefsPropsUtil.getString(
154                 companyId, PropsKeys.LDAP_BASE_DN + postfix);
155 
156             ctx = PortalLDAPUtil.getContext(ldapServerId, companyId);
157 
158             if (ctx == null) {
159                 throw new SystemException("Failed to bind to the LDAP server");
160             }
161 
162             String filter = PrefsPropsUtil.getString(
163                 companyId, PropsKeys.LDAP_AUTH_SEARCH_FILTER + postfix);
164 
165             if (_log.isDebugEnabled()) {
166                 _log.debug("Search filter before transformation " + filter);
167             }
168 
169             filter = StringUtil.replace(
170                 filter,
171                 new String[] {
172                     "@company_id@", "@email_address@", "@screen_name@"
173                 },
174                 new String[] {
175                     String.valueOf(companyId), emailAddress, screenName
176                 });
177 
178             if (_log.isDebugEnabled()) {
179                 _log.debug("Search filter after transformation " + filter);
180             }
181 
182             SearchControls cons = new SearchControls(
183                 SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
184 
185             NamingEnumeration<SearchResult> enu = ctx.search(
186                 baseDN, filter, cons);
187 
188             if (enu.hasMoreElements()) {
189                 if (_log.isDebugEnabled()) {
190                     _log.debug("Search filter returned at least one result");
191                 }
192 
193                 Binding binding = enu.nextElement();
194 
195                 Attributes attrs = PortalLDAPUtil.getUserAttributes(
196                     ldapServerId, companyId, ctx,
197                     PortalLDAPUtil.getNameInNamespace(
198                         ldapServerId, companyId, binding));
199 
200                 return PortalLDAPImporterUtil.importLDAPUser(
201                     ldapServerId, companyId, ctx, attrs, StringPool.BLANK,
202                     true);
203             }
204             else {
205                 return null;
206             }
207         }
208         catch (Exception e) {
209             if (_log.isWarnEnabled()) {
210                 _log.warn("Problem accessing LDAP server " + e.getMessage());
211             }
212 
213             if (_log.isDebugEnabled()) {
214                 _log.debug(e, e);
215             }
216 
217             throw new SystemException(
218                 "Problem accessing LDAP server " + e.getMessage());
219         }
220         finally {
221             if (ctx != null) {
222                 ctx.close();
223             }
224         }
225     }
226 
227     protected User importLDAPUser(
228             long companyId, String emailAddress, String screenName)
229         throws Exception {
230 
231         long[] ldapServerIds = StringUtil.split(
232             PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
233 
234         if (ldapServerIds.length <= 0) {
235             ldapServerIds = new long[] {0};
236         }
237 
238         for (long ldapServerId : ldapServerIds) {
239             User user = importLDAPUser(
240                 ldapServerId, companyId, emailAddress, screenName);
241 
242             if (user != null) {
243                 return user;
244             }
245         }
246 
247         if (_log.isDebugEnabled()) {
248             if (Validator.isNotNull(emailAddress)) {
249                 _log.debug(
250                     "User with the email address " + emailAddress +
251                         " was not found in any LDAP servers");
252             }
253             else {
254                 _log.debug(
255                     "User with the screen name " + screenName +
256                         " was not found in any LDAP servers");
257             }
258         }
259 
260         return null;
261     }
262 
263     private static Log _log = LogFactoryUtil.getLog(CASAutoLogin.class);
264 
265 }