Mapping LDAP attribute to Liferay user display language

≡放荡痞女 提交于 2020-01-25 10:26:06

问题


We are using Liferay 6.2 GA4, which allows you to map only few basic attributes for LDAP user import: screenName, password, emailAddress, firstName, lastName, jobTitle and group. If you want to map some custom fields you have to use custom mapping. Both cases are working fine but what we really want is to map LDAP attribute preferredLanguage to user languageId so the user language in Liferay is set based on LDAP value. What we have tried:

  • Map preferredLanguage to languageId in standard ldap.user.mappings so the entry in portalpreferences table entry looks like this:

    ...<preference>
        <name>ldap.user.mappings.21597</name>
        <value>emailAddress=uid[$NEW_LINE$]firstName=givenName[$NEW_LINE$]group=memberOf[$NEW_LINE$]lastName=sn[$NEW_LINE$]languageId=preferredLanguage</value>
    </preference>...
    
  • Map it in ldap.user.custom.mappings so portalpreferences table entry is:

    ...<preference>
        <name>ldap.user.custom.mappings.21597</name>
        <value>...ourCustomAttributes...[$NEW_LINE$]languageId=preferredLanguage</value>
    </preference>...
    

Neither works. The only thing what is working is to create custom user field in Liferay e.g. custLanguage and map preferredLanguage to this field. But then we don't know how to pass value from custLanguage to users display settings languageId so the language for that user is changed automatically. Lot of users had problems with Liferay language LDAP import, e.g. https://issues.liferay.com/browse/LPS-23143. I assume that if you can add languageId to ignore list you can also import it.

This question corresponds with our problem but the solution is to use custom fields and we don't know how to elaborate on it further. So our questions are:

  • Is it possible to map our custom LDAP attribute preferredLanguage directly to languageId of Liferay user?
  • If the above is not possible and you have to use custom attributes how we should pass the value from custom user language attribute to his language display settings?

回答1:


As mentioned in comments, the only way I've found to perform such task is to write a custom LDAPImporterImpl and put it into an EXT plug-in. Here is a snippet of my code:

import com.liferay.portal.security.ldap.PortalLDAPImporterImpl
// other imports 

public class CustomPortalLDAPImporterImpl extends PortalLDAPImporterImpl {

  @Override
  public User importLDAPUser(long ldapServerId, long companyId, LdapContext ldapContext, Attributes attributes, String password) throws Exception {
    User user = super.importLDAPUser(ldapServerId, companyId, ldapContext, attributes, password);
    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
    String baseDN = PrefsPropsUtil.getString(companyId, PropsKeys.LDAP_BASE_DN + postfix);
    Attributes completeUserAttributes = getUserLdapAttributes(ldapContext, user, baseDN);
    setUserAddress(user, completeUserAttributes);
    setUserPhones(user, completeUserAttributes);
    return user;
  }

  // ...

  private Attributes getUserLdapAttributes(LdapContext ctx, User user, String baseDN) {
    String searchFilter = "(&(objectClass=person)(sAMAccountName=" + user.getScreenName() + "))";
    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    NamingEnumeration<SearchResult> results;
    try {
      log.debug("Searching LDAP with the following filter: " + searchFilter);
      results = ctx.search(baseDN, searchFilter, searchControls);
      SearchResult searchResult = null;
      if(results.hasMoreElements()) {
        searchResult = (SearchResult) results.nextElement();
        if(results.hasMoreElements()) {
          log.error("Matched multiple users for the user: " + user.getScreenName());
          return null;
        }
        Attributes attributes = searchResult.getAttributes();
        return attributes;
      } else {
        log.error("No LDAP record for username [" + user.getScreenName() + "] found.");
      }
    } catch (NamingException e) {
      log.error("Error getting attributes for user [" + user.getScreenName() + "]: " + e.getMessage());
    }
    return null;
  }

  // ...

}

You also have to define this importer in the META-INF/ext-spring.xml file of the EXT plug-in:

<?xml version="1.0"?>

<beans
    default-destroy-method="destroy"
    default-init-method="afterPropertiesSet"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" >

    <bean id="ldapToPortalConverter" class="com.liferay.portal.security.ldap.DefaultLDAPToPortalConverter" />
    <bean id="portalToLDAPConverter" class="com.liferay.portal.security.ldap.DefaultPortalToLDAPConverter" />
    <bean id="com.liferay.portal.security.ldap.PortalLDAPExporterUtil" class="com.liferay.portal.security.ldap.PortalLDAPExporterUtil">
        <property name="portalLDAPExporter">
            <bean class="com.liferay.portal.security.ldap.PortalLDAPExporterImpl">
                <property name="portalToLDAPConverter" ref="portalToLDAPConverter" />
            </bean>
        </property>
    </bean>
    <bean id="com.liferay.portal.security.ldap.PortalLDAPImporterUtil" class="com.liferay.portal.security.ldap.PortalLDAPImporterUtil">
        <property name="portalLDAPImporter">
            <bean class="ch.openinteractive.familea.security.ldap.CustomPortalLDAPImporterImpl">
                <property name="LDAPToPortalConverter" ref="ldapToPortalConverter" />
            </bean>
        </property>
    </bean>
</beans>

I'd be happy if someone come with a better, less invasive solution.



来源:https://stackoverflow.com/questions/30976211/mapping-ldap-attribute-to-liferay-user-display-language

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!