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