PageRenderTime 40ms CodeModel.GetById 29ms app.highlight 9ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/apps/portal-security-sso/portal-security-sso-opensso-impl/src/main/java/com/liferay/portal/security/sso/opensso/internal/auto/login/OpenSSOAutoLogin.java

https://github.com/danielreuther/liferay-portal
Java | 342 lines | 243 code | 62 blank | 37 comment | 26 complexity | 68f3f9ec20ea3dbd8ffe73cf1f4d7f99 MD5 | raw file
  1/**
  2 * Copyright (c) 2000-present 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
 15package com.liferay.portal.security.sso.opensso.internal.auto.login;
 16
 17import com.liferay.petra.string.StringBundler;
 18import com.liferay.petra.string.StringPool;
 19import com.liferay.portal.kernel.exception.ContactNameException;
 20import com.liferay.portal.kernel.exception.PortalException;
 21import com.liferay.portal.kernel.exception.SystemException;
 22import com.liferay.portal.kernel.exception.UserEmailAddressException;
 23import com.liferay.portal.kernel.log.Log;
 24import com.liferay.portal.kernel.log.LogFactoryUtil;
 25import com.liferay.portal.kernel.model.Company;
 26import com.liferay.portal.kernel.model.CompanyConstants;
 27import com.liferay.portal.kernel.model.User;
 28import com.liferay.portal.kernel.module.configuration.ConfigurationProvider;
 29import com.liferay.portal.kernel.security.auth.ScreenNameGenerator;
 30import com.liferay.portal.kernel.security.auto.login.AutoLogin;
 31import com.liferay.portal.kernel.security.auto.login.BaseAutoLogin;
 32import com.liferay.portal.kernel.security.sso.OpenSSO;
 33import com.liferay.portal.kernel.service.CompanyLocalService;
 34import com.liferay.portal.kernel.service.ServiceContext;
 35import com.liferay.portal.kernel.service.UserLocalService;
 36import com.liferay.portal.kernel.settings.CompanyServiceSettingsLocator;
 37import com.liferay.portal.kernel.theme.ThemeDisplay;
 38import com.liferay.portal.kernel.util.LocaleUtil;
 39import com.liferay.portal.kernel.util.ParamUtil;
 40import com.liferay.portal.kernel.util.Portal;
 41import com.liferay.portal.kernel.util.PrefsPropsUtil;
 42import com.liferay.portal.kernel.util.PropsKeys;
 43import com.liferay.portal.kernel.util.Validator;
 44import com.liferay.portal.kernel.util.WebKeys;
 45import com.liferay.portal.security.exportimport.UserImporter;
 46import com.liferay.portal.security.sso.opensso.configuration.OpenSSOConfiguration;
 47import com.liferay.portal.security.sso.opensso.constants.OpenSSOConstants;
 48import com.liferay.portal.security.sso.opensso.constants.OpenSSOWebKeys;
 49import com.liferay.portal.security.sso.opensso.exception.StrangersNotAllowedException;
 50import com.liferay.portal.util.PropsValues;
 51
 52import java.util.Calendar;
 53import java.util.Locale;
 54import java.util.Map;
 55
 56import javax.servlet.http.HttpServletRequest;
 57import javax.servlet.http.HttpServletResponse;
 58
 59import org.osgi.service.component.annotations.Component;
 60import org.osgi.service.component.annotations.Reference;
 61
 62/**
 63 * Participates in every unauthenticated HTTP request to Liferay Portal.
 64 *
 65 * <p>
 66 * This class queries the OpenSSO server for the name of the OpenSSO token
 67 * cookie and any additional cookies. These are then extracted from the HTTP
 68 * request and forwarded to the OpenSSO server to validate the user's
 69 * authentication status.
 70 * </p>
 71 *
 72 * <p>
 73 * If the cookies are validated, another request is made to the OpenSSO server
 74 * to retrieve all the user's attributes. These are mapped to Liferay Portal
 75 * user attributes using the configured mappings. If Import from LDAP is
 76 * enabled, then the user is imported and logged in. Otherwise a new user is
 77 * created and logged in.
 78 * </p>
 79 *
 80 * @author Brian Wing Shun Chan
 81 * @author Prashant Dighe
 82 */
 83@Component(
 84	configurationPid = "com.liferay.portal.security.sso.opensso.configuration.OpenSSOConfiguration",
 85	immediate = true, service = AutoLogin.class
 86)
 87public class OpenSSOAutoLogin extends BaseAutoLogin {
 88
 89	@Override
 90	protected String[] doLogin(
 91			HttpServletRequest httpServletRequest,
 92			HttpServletResponse httpServletResponse)
 93		throws Exception {
 94
 95		long companyId = _portal.getCompanyId(httpServletRequest);
 96
 97		OpenSSOConfiguration openSSOConfiguration = _getOpenSSOConfiguration(
 98			companyId);
 99
100		if (!openSSOConfiguration.enabled() ||
101			!_openSSO.isAuthenticated(
102				httpServletRequest, openSSOConfiguration.serviceURL())) {
103
104			return null;
105		}
106
107		Map<String, String> nameValues = _openSSO.getAttributes(
108			httpServletRequest, openSSOConfiguration.serviceURL());
109
110		String openSSOScreenName = nameValues.get(
111			openSSOConfiguration.screenNameAttr());
112		String emailAddress = nameValues.get(
113			openSSOConfiguration.emailAddressAttr());
114		String firstName = nameValues.get(openSSOConfiguration.firstNameAttr());
115		String lastName = nameValues.get(openSSOConfiguration.lastNameAttr());
116
117		if (_log.isDebugEnabled()) {
118			_log.debug(
119				StringBundler.concat(
120					"Validating user information for ", firstName, " ",
121					lastName, " with screen name ", openSSOScreenName,
122					" and email address ", emailAddress));
123		}
124
125		User user = null;
126
127		String screenName = openSSOScreenName;
128
129		if (PrefsPropsUtil.getBoolean(
130				companyId, PropsKeys.USERS_SCREEN_NAME_ALWAYS_AUTOGENERATE)) {
131
132			user = _userLocalService.fetchUserByEmailAddress(
133				companyId, emailAddress);
134
135			if (user != null) {
136				screenName = _screenNameGenerator.generate(
137					companyId, user.getUserId(), emailAddress);
138			}
139		}
140
141		if (openSSOConfiguration.importFromLDAP()) {
142			try {
143				String authType = PrefsPropsUtil.getString(
144					companyId, PropsKeys.COMPANY_SECURITY_AUTH_TYPE,
145					PropsValues.COMPANY_SECURITY_AUTH_TYPE);
146
147				if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
148					user = _userImporter.importUser(
149						companyId, StringPool.BLANK, screenName);
150				}
151				else {
152					user = _userImporter.importUser(
153						companyId, emailAddress, StringPool.BLANK);
154				}
155			}
156			catch (SystemException systemException) {
157
158				// LPS-52675
159
160				if (_log.isDebugEnabled()) {
161					_log.debug(systemException);
162				}
163			}
164		}
165		else {
166			if (Validator.isNull(emailAddress)) {
167				return doHandleException(
168					httpServletRequest, httpServletResponse,
169					new Exception("Email address is null"));
170			}
171		}
172
173		if (user == null) {
174			user = _userLocalService.fetchUserByScreenName(
175				companyId, screenName);
176		}
177
178		if (user == null) {
179			ThemeDisplay themeDisplay =
180				(ThemeDisplay)httpServletRequest.getAttribute(
181					WebKeys.THEME_DISPLAY);
182
183			Locale locale = LocaleUtil.getDefault();
184
185			if (themeDisplay != null) {
186
187				// ThemeDisplay should never be null, but some users complain of
188				// this error. Cause is unknown.
189
190				locale = themeDisplay.getLocale();
191			}
192
193			try {
194				_checkAddUser(companyId, emailAddress);
195
196				if (_log.isDebugEnabled()) {
197					_log.debug("Adding user " + screenName);
198				}
199
200				user = _addUser(
201					companyId, firstName, lastName, emailAddress, screenName,
202					locale);
203			}
204			catch (PortalException portalException) {
205				if (_log.isDebugEnabled()) {
206					_log.debug(
207						StringBundler.concat(
208							"Failed to import OpenSSO user '",
209							openSSOScreenName, "': ",
210							portalException.getMessage()),
211						portalException);
212				}
213
214				if (portalException instanceof ContactNameException) {
215					httpServletRequest.setAttribute(
216						OpenSSOWebKeys.OPEN_SSO_ERROR,
217						ContactNameException.class.getSimpleName());
218				}
219				else {
220					Class<?> clazz = portalException.getClass();
221
222					httpServletRequest.setAttribute(
223						OpenSSOWebKeys.OPEN_SSO_ERROR, clazz.getSimpleName());
224				}
225
226				httpServletRequest.setAttribute(
227					OpenSSOWebKeys.OPEN_SSO_SUBJECT_SCREEN_NAME,
228					openSSOScreenName);
229
230				return null;
231			}
232		}
233
234		String currentURL = _portal.getCurrentURL(httpServletRequest);
235
236		if (currentURL.contains("/portal/login")) {
237			String redirect = ParamUtil.getString(
238				httpServletRequest, "redirect");
239
240			if (Validator.isNotNull(redirect)) {
241				redirect = _portal.escapeRedirect(redirect);
242			}
243			else {
244				redirect = _portal.getPathMain();
245			}
246
247			httpServletRequest.setAttribute(
248				AutoLogin.AUTO_LOGIN_REDIRECT, redirect);
249		}
250
251		String[] credentials = new String[3];
252
253		credentials[0] = String.valueOf(user.getUserId());
254		credentials[1] = user.getPassword();
255		credentials[2] = Boolean.TRUE.toString();
256
257		return credentials;
258	}
259
260	private User _addUser(
261			long companyId, String firstName, String lastName,
262			String emailAddress, String screenName, Locale locale)
263		throws PortalException {
264
265		long creatorUserId = 0;
266		boolean autoPassword = true;
267		String password1 = null;
268		String password2 = null;
269		boolean autoScreenName = false;
270		String middleName = StringPool.BLANK;
271		long prefixId = 0;
272		long suffixId = 0;
273		boolean male = true;
274		int birthdayMonth = Calendar.JANUARY;
275		int birthdayDay = 1;
276		int birthdayYear = 1970;
277		String jobTitle = StringPool.BLANK;
278		long[] groupIds = null;
279		long[] organizationIds = null;
280		long[] roleIds = null;
281		long[] userGroupIds = null;
282		boolean sendEmail = false;
283
284		return _userLocalService.addUser(
285			creatorUserId, companyId, autoPassword, password1, password2,
286			autoScreenName, screenName, emailAddress, locale, firstName,
287			middleName, lastName, prefixId, suffixId, male, birthdayMonth,
288			birthdayDay, birthdayYear, jobTitle, groupIds, organizationIds,
289			roleIds, userGroupIds, sendEmail, new ServiceContext());
290	}
291
292	private void _checkAddUser(long companyId, String emailAddress)
293		throws PortalException {
294
295		Company company = _companyLocalService.getCompany(companyId);
296
297		if (!company.isStrangers()) {
298			throw new StrangersNotAllowedException(companyId);
299		}
300
301		if (!company.isStrangersWithMx() &&
302			company.hasCompanyMx(emailAddress)) {
303
304			throw new UserEmailAddressException.MustNotUseCompanyMx(
305				emailAddress);
306		}
307	}
308
309	private OpenSSOConfiguration _getOpenSSOConfiguration(long companyId)
310		throws Exception {
311
312		return _configurationProvider.getConfiguration(
313			OpenSSOConfiguration.class,
314			new CompanyServiceSettingsLocator(
315				companyId, OpenSSOConstants.SERVICE_NAME));
316	}
317
318	private static final Log _log = LogFactoryUtil.getLog(
319		OpenSSOAutoLogin.class);
320
321	@Reference
322	private CompanyLocalService _companyLocalService;
323
324	@Reference
325	private ConfigurationProvider _configurationProvider;
326
327	@Reference
328	private OpenSSO _openSSO;
329
330	@Reference
331	private Portal _portal;
332
333	@Reference
334	private ScreenNameGenerator _screenNameGenerator;
335
336	@Reference
337	private UserImporter _userImporter;
338
339	@Reference
340	private UserLocalService _userLocalService;
341
342}