liferay ldap配置与相关代码

1.下载LDAP server 并安装, liferay支持如下的server,推荐使用apacheds,或openLDAP


 

2.下载一个LDAP客户端工具,官方网站都有提供 ,推荐使用 jxplorer,测试能否正常连接。

 

3. Enterprise Admin->setting->authentication->LDAP,Enable使用LDAP验证,Required是否必须通过LDAP验证,如果不勾选通过liferay验证即可。


	/**
	 * LDAP验证
	 * @param companyId
	 * @param emailAddress
	 * @param screenName
	 * @param userId
	 * @param password
	 * @return
	 * @throws Exception
	 */
	protected int authenticate(
			long companyId, String emailAddress, String screenName, long userId,
			String password)
		throws Exception {
		//是否需要LDAP验证
		if (!PortalLDAPUtil.isAuthEnabled(companyId)) {
			if (_log.isDebugEnabled()) {
				_log.debug("Authenticator is not enabled");
			}

			return SUCCESS;
		}

		if (_log.isDebugEnabled()) {
			_log.debug("Authenticator is enabled");
		}

		// Make exceptions for omniadmins so that if they break the LDAP
		// configuration, they can still login to fix the problem
		//如果此用户是管理员的角色就返回成功
		if (authenticateOmniadmin(companyId, emailAddress, userId) == SUCCESS) {
			return SUCCESS;
		}
		//相对DN
		String baseDN = PrefsPropsUtil.getString(
			companyId, PropsUtil.LDAP_BASE_DN);

		LdapContext ctx = PortalLDAPUtil.getContext(companyId);

		if (ctx == null) {
			//查看LDAP验证是否是必须的
			return authenticateRequired(
				companyId, userId, emailAddress, FAILURE);
		}

		//  Process LDAP auth search filter

		String filter = PortalLDAPUtil.getAuthSearchFilter(
			companyId, emailAddress, screenName, String.valueOf(userId));

		try {
			SearchControls cons = new SearchControls(
				SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);

			NamingEnumeration<SearchResult> enu = ctx.search(
				baseDN, filter, cons);

			if (enu.hasMore()) {
				if (_log.isDebugEnabled()) {
					_log.debug("Search filter returned at least one result");
				}

				SearchResult result = enu.next();

				String fullUserDN = PortalLDAPUtil.getNameInNamespace(
					companyId, result);

				Attributes attrs = PortalLDAPUtil.getAttributes(
					ctx, fullUserDN);

				LDAPAuthResult ldapAuthResult = authenticate(
					ctx, companyId, attrs, fullUserDN, password);

				// Process LDAP failure codes

				String errorMessage = ldapAuthResult.getErrorMessage();

				if (errorMessage != null) {
					if (errorMessage.indexOf(PrefsPropsUtil.getString(
							companyId, PropsUtil.LDAP_ERROR_USER_LOCKOUT))
								!= -1) {

						throw new UserLockoutException();
					}
					else if (errorMessage.indexOf(PrefsPropsUtil.getString(
						companyId, PropsUtil.LDAP_ERROR_PASSWORD_EXPIRED))
							!= -1) {

						throw new PasswordExpiredException();
					}
				}

				if (!ldapAuthResult.isAuthenticated()) {
					//查看LDAP验证是否是必须的
					return authenticateRequired(
						companyId, userId, emailAddress, FAILURE);
				}

				// Get user or create from LDAP

				User user = PortalLDAPUtil.importLDAPUser(
					companyId, ctx, attrs, password, true);

				// Process LDAP success codes

				String resultCode = ldapAuthResult.getResponseControl();

				if (resultCode.equals(LDAPAuth.RESULT_PASSWORD_RESET)) {
					UserLocalServiceUtil.updatePasswordReset(
						user.getUserId(), true);
				}
				else if (
					resultCode.equals(LDAPAuth.RESULT_PASSWORD_EXP_WARNING)) {

					UserLocalServiceUtil.updatePasswordReset(
						user.getUserId(), true);
				}
			}
			else {
				if (_log.isDebugEnabled()) {
					_log.debug("Search filter did not return any results");
				}
				//查看LDAP验证是否是必须的
				return authenticateRequired(
					companyId, userId, emailAddress, DNE);
			}
		}
		catch (Exception e) {
			_log.error("Problem accessing LDAP server: " + e.getMessage());
			//查看LDAP验证是否是必须的
			if (authenticateRequired(
					companyId, userId, emailAddress, FAILURE) == FAILURE) {

				throw e;
			}
		}
		finally {
			ctx.close();
		}

		return SUCCESS;
	}
 

4.Default Values选择你使用的DS服务 。

 

5.测试连接能否成功。这些参数要根据自已的服务来填写。

测试成功

	/**
	 * 获得连接上下文
	 * @param companyId
	 * @return
	 * @throws Exception
	 */
	public static LdapContext getContext(long companyId) throws Exception {
		//连接地址(优先取数据库中)
		String baseProviderURL = PrefsPropsUtil.getString(
			companyId, PropsUtil.LDAP_BASE_PROVIDER_URL);
		//用户地址(优先取数据库中)
		String pricipal = PrefsPropsUtil.getString(
			companyId, PropsUtil.LDAP_SECURITY_PRINCIPAL);
		//连接密码(优先取数据库中)
		String credentials = PrefsPropsUtil.getString(
			companyId, PropsUtil.LDAP_SECURITY_CREDENTIALS);

		return getContext(companyId, baseProviderURL, pricipal, credentials);
	}

	public static LdapContext getContext(
			long companyId, String providerURL, String pricipal,
			String credentials)
		throws Exception {

		Properties env = new Properties();

		env.put(
			Context.INITIAL_CONTEXT_FACTORY,
			PrefsPropsUtil.getString(
				companyId, PropsUtil.LDAP_FACTORY_INITIAL));
		env.put(Context.PROVIDER_URL, providerURL);
		env.put(Context.SECURITY_PRINCIPAL, pricipal);
		env.put(Context.SECURITY_CREDENTIALS, credentials);

		LogUtil.debug(_log, env);

		LdapContext ctx = null;

		try {
			ctx = new InitialLdapContext(env, null);
		}
		catch (Exception e) {
			if (_log.isWarnEnabled()) {
				_log.warn("Failed to bind to the LDAP server");
			}

			if (_log.isDebugEnabled()) {
				_log.debug(e);
			}
		}

		return ctx;
	}

 

6.测试用户:Authentication search Filter验证过滤语句,现在是过滤email,Test LDAP Users这个按钮是不会调用这个过滤的,Import Search Filter测试用户过滤语句。下面是liferay数据与ldap数据一对应的关系。

 测试成功

 

	/**
	 * 测试取用户列表
	 * @param companyId
	 * @param ctx
	 * @param maxResults
	 * @return
	 * @throws Exception
	 */
	public static NamingEnumeration<SearchResult> getUsers(
			long companyId, LdapContext ctx, int maxResults)
		throws Exception {

		String baseDN = PrefsPropsUtil.getString(
			companyId, PropsUtil.LDAP_BASE_DN);
		String userFilter = PrefsPropsUtil.getString(
			companyId, PropsUtil.LDAP_IMPORT_USER_SEARCH_FILTER);

		return getUsers(companyId, ctx, maxResults, baseDN, userFilter);
	}

	public static NamingEnumeration<SearchResult> getUsers(
			long companyId, LdapContext ctx, int maxResults, String baseDN,
			String userFilter)
		throws Exception {

		SearchControls cons = new SearchControls(
			SearchControls.SUBTREE_SCOPE, maxResults, 0, null, false, false);

		return ctx.search(baseDN, userFilter, cons);
	}

 

7.测试取得用户组织,基本上同上就不详解,仅贴出成功画面和相关代码

	/**
	 * 测试用户组织
	 * @param companyId
	 * @param ctx
	 * @param maxResults
	 * @return
	 * @throws Exception
	 */
	public static NamingEnumeration<SearchResult> getGroups(
			long companyId, LdapContext ctx, int maxResults)
		throws Exception {

		String baseDN = PrefsPropsUtil.getString(
			companyId, PropsUtil.LDAP_BASE_DN);
		String groupFilter = PrefsPropsUtil.getString(
			companyId, PropsUtil.LDAP_IMPORT_GROUP_SEARCH_FILTER);

		return getGroups(companyId, ctx, maxResults, baseDN, groupFilter);
	}

	public static NamingEnumeration<SearchResult> getGroups(
			long companyId, LdapContext ctx, int maxResults, String baseDN,
			String groupFilter)
		throws Exception {

		SearchControls cons = new SearchControls(
			SearchControls.SUBTREE_SCOPE, maxResults, 0, null, false, false);

		return ctx.search(baseDN, groupFilter, cons);
	}
 

8.导入导出配置:Import Enabled:是否导入,导入时密码为空 Import on Startup Enabled:启动导入。Import Interval:导入间隔时间,注意时间太短会影响性能。Export Enabled:是否导出, 在用户登陆时和修改用户信息时都会导出至LDAP但不导出密码,在修改时如果修改了密码才会把密码也导出进去,如果密码未导入至LDAP并且前面的 Required也勾选了,那么LDAP验证不会通过 。后面三个为导出的设置。

 

	/**
	 * 从LDAP中导入用户
	 * @param companyId
	 * @param ctx
	 * @param attrs
	 * @param password
	 * @param importGroupMembership
	 * @return
	 * @throws Exception
	 */
	public static User importLDAPUser(
			long companyId, LdapContext ctx, Attributes attrs, String password,
			boolean importGroupMembership)
		throws Exception {

		AttributesTransformer attrsTransformer =
			AttributesTransformerFactory.getInstance();

		attrs = attrsTransformer.transformUser(attrs);

		Properties userMappings = getUserMappings(companyId);

		LogUtil.debug(_log, userMappings);

		User defaultUser = UserLocalServiceUtil.getDefaultUser(companyId);

		boolean autoPassword = false;
		boolean updatePassword = true;

		if (password.equals(StringPool.BLANK)) {
			autoPassword = true;
			updatePassword = false;
		}

		long creatorUserId = 0;
		boolean passwordReset = false;
		boolean autoScreenName = false;
		String screenName = LDAPUtil.getAttributeValue(
			attrs, userMappings.getProperty("screenName")).toLowerCase();
		String emailAddress = LDAPUtil.getAttributeValue(
			attrs, userMappings.getProperty("emailAddress"));
		Locale locale = defaultUser.getLocale();
		String firstName = LDAPUtil.getAttributeValue(
			attrs, userMappings.getProperty("firstName"));
		String middleName = LDAPUtil.getAttributeValue(
			attrs, userMappings.getProperty("middleName"));
		String lastName = LDAPUtil.getAttributeValue(
			attrs, userMappings.getProperty("lastName"));

		if (Validator.isNull(firstName) || Validator.isNull(lastName)) {
			String fullName = LDAPUtil.getAttributeValue(
				attrs, userMappings.getProperty("fullName"));

			String[] names = LDAPUtil.splitFullName(fullName);

			firstName = names[0];
			middleName = names[1];
			lastName = names[2];
		}

		int prefixId = 0;
		int suffixId = 0;
		boolean male = true;
		int birthdayMonth = Calendar.JANUARY;
		int birthdayDay = 1;
		int birthdayYear = 1970;
		String jobTitle = LDAPUtil.getAttributeValue(
			attrs, userMappings.getProperty("jobTitle"));
		long[] organizationIds = new long[0];
		boolean sendEmail = false;

		if (_log.isDebugEnabled()) {
			_log.debug(
				"Screen name " + screenName + " and email address " +
					emailAddress);
		}

		if (Validator.isNull(screenName) || Validator.isNull(emailAddress)) {
			if (_log.isWarnEnabled()) {
				_log.warn(
					"Cannot add user because screen name and email address " +
						"are required");
			}

			return null;
		}

		User user = null;

		try {

			// Find corresponding portal user

			String authType = PrefsPropsUtil.getString(
				companyId, PropsUtil.COMPANY_SECURITY_AUTH_TYPE,
				PropsValues.COMPANY_SECURITY_AUTH_TYPE);

			if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
				user = UserLocalServiceUtil.getUserByScreenName(
					companyId, screenName);
			}
			else {
				user = UserLocalServiceUtil.getUserByEmailAddress(
					companyId, emailAddress);
			}

			// Skip if is default user

			if (user.isDefaultUser()) {
				return user;
			}

			// Skip import if user fields has been already synced and if
			// import is part of a scheduled import

			Date ldapUserModifiedDate = null;

			String modifiedDate = LDAPUtil.getAttributeValue(
				attrs, "modifyTimestamp");

			try {
				DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

				ldapUserModifiedDate = dateFormat.parse(modifiedDate);

				if (ldapUserModifiedDate.equals(user.getModifiedDate()) &&
					autoPassword) {

					if (_log.isDebugEnabled()) {
						_log.debug(
							"User is already syncronized, skipping user " +
								user.getEmailAddress());
					}

					return user;
				}
			}
			catch (ParseException pe) {
				if (_log.isDebugEnabled()) {
					_log.debug(
						"Unable to parse LDAP modify timestamp " +
							modifiedDate);
				}

				_log.debug(pe, pe);
			}

			Contact contact = user.getContact();

			Calendar birthdayCal = CalendarFactoryUtil.getCalendar();

			birthdayCal.setTime(contact.getBirthday());

			birthdayMonth = birthdayCal.get(Calendar.MONTH);
			birthdayDay = birthdayCal.get(Calendar.DATE);
			birthdayYear = birthdayCal.get(Calendar.YEAR);

			// User exists so update user information

			if (updatePassword) {
				user = UserLocalServiceUtil.updatePassword(
					user.getUserId(), password, password, passwordReset,
					true);
			}

			user = UserLocalServiceUtil.updateUser(
				user.getUserId(), password, user.isPasswordReset(), screenName,
				emailAddress, user.getLanguageId(), user.getTimeZoneId(),
				user.getGreeting(), user.getComments(), firstName, middleName,
				lastName, contact.getPrefixId(), contact.getSuffixId(),
				contact.getMale(), birthdayMonth, birthdayDay, birthdayYear,
				contact.getSmsSn(), contact.getAimSn(), contact.getIcqSn(),
				contact.getJabberSn(), contact.getMsnSn(), contact.getSkypeSn(),
				contact.getYmSn(), jobTitle, user.getOrganizationIds());

			if (ldapUserModifiedDate != null) {
				UserLocalServiceUtil.updateModifiedDate(
					user.getUserId(), ldapUserModifiedDate);
			}
		}
		catch (NoSuchUserException nsue) {

			// User does not exist so create

		}

		if (user == null) {
			try {
				if (_log.isDebugEnabled()) {
					_log.debug("Adding user to portal " + emailAddress);
				}

				user = UserLocalServiceUtil.addUser(
					creatorUserId, companyId, autoPassword, password, password,
					autoScreenName, screenName, emailAddress, locale, firstName,
					middleName, lastName, prefixId, suffixId, male,
					birthdayMonth, birthdayDay, birthdayYear, jobTitle,
					organizationIds, sendEmail);
			}
			catch (Exception e){
				_log.error(
					"Problem adding user with screen name " + screenName +
						" and email address " + emailAddress,
					e);
			}
		}

		// Import user groups and membership

		if (importGroupMembership && (user != null)) {
			String userMappingsGroup = userMappings.getProperty("group");

			if (userMappingsGroup != null) {
				Attribute attr = attrs.get(userMappingsGroup);

				if (attr != null){
					_importGroupsAndMembershipFromLDAPUser(
						companyId, ctx, user.getUserId(), attr);
				}
			}
		}

		return user;
	}
 
/**
	 * 将用户导出至LDAP
	 * @param user
	 * @throws Exception
	 */
	public static void exportToLDAP(User user) throws Exception {
		long companyId = user.getCompanyId();

		if (!isAuthEnabled(companyId) || !isExportEnabled(companyId)) {
			return;
		}

		LdapContext ctx = getContext(companyId);

		if (ctx == null) {
			return;
		}

		Properties userMappings = getUserMappings(companyId);
		Binding binding = getUser(user.getCompanyId(), user.getScreenName());
		String name = StringPool.BLANK;

		if (binding == null) {

			// Generate full DN based on user DN

			StringMaker sm = new StringMaker();

			sm.append(userMappings.getProperty("screenName"));
			sm.append(StringPool.EQUAL);
			sm.append(user.getScreenName());
			sm.append(StringPool.COMMA);
			sm.append(getUsersDN(companyId));

			name = sm.toString();

			// Create new user in LDAP

			LDAPUser ldapUser = (LDAPUser)Class.forName(
				PropsValues.LDAP_USER_IMPL).newInstance();

			ldapUser.setUser(user);

			ctx.bind(name, ldapUser);
		}
		else {

			// Modify existing LDAP user record

			name = getNameInNamespace(companyId, binding);

			Modifications mods = Modifications.getInstance();

			if (user.isPasswordModified() &&
				Validator.isNotNull(user.getPasswordUnencrypted())) {

				mods.addItem(
					userMappings.getProperty("password"),
					user.getPasswordUnencrypted());
			}

			mods.addItem(
				userMappings.getProperty("emailAddress"),
				user.getEmailAddress());

			ModificationItem[] modItems = mods.getItems();

			ctx.modifyAttributes(name, modItems);
		}

		ctx.close();
	}

 

9.Use LDAP Password Policy:是使用LDAP的密码策略,这个主要用在验证方面,不推荐使用。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值