【问题标题】:Programmatically connect LDAP and authenticate credentials in AEM以编程方式连接 LDAP 并在 AEM 中验证凭据
【发布时间】:2019-12-04 10:33:03
【问题描述】:

我想在 AEM 中使用在 OSGi 中解析的 maven 依赖项以编程方式连接到 LDAP

面临的方法和后续问题:-

1.无法使用

@Reference
private ExternalIdentityProviderManager externalIdentityProviderManager;

final String externalId = request.getParameter("externalId");
final String externalPassword = request.getParameter("externalPassword");

final ExternalIdentityProvider idap = externalIdentityProviderManager.getProvider("ldap");
final SimpleCredentials credentials = new SimpleCredentials(externalId, externalPassword.toCharArray());
final ExternalUser externalUser = idap.authenticate(credentials);

因为此身份提供程序配置仅存在于作者环境中,而不存在于发布服务器中(根据要求)。

2。尝试使用

<dependency>
    <groupId>org.apache.directory.api</groupId>
    <artifactId>api-ldap-client-api</artifactId>
    <version>2.0.0.AM4</version>
</dependency>

解决依赖关系。它解决了我的编译时错误,但这不是一个“准备好 osgi”的库,因此 无法在 OSGi 中安装。如果手动这样做,它会有更多未解决的依赖项

此方法的

代码参考 - https://directory.apache.org/api/user-guide/2.1-connection-disconnection.html & https://directory.apache.org/api/user-guide/2.10-ldap-connection-template.html

3。我也试过用

String rootDN = "uid=admin,ou=system";
String rootPWD = "secret";
Hashtable < String, String > environment = new Hashtable < String, String > ();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, "ldap://localhost:10389");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, rootDN);
environment.put(Context.SECURITY_CREDENTIALS, rootPWD);
DirContext dirContext = null;
NamingEnumeration < ? > results = null;
dirContext = new InitialDirContext(environment);
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String userId = "abhishek";
String userPwd = "{SSHA}ip/DD+zUhv22NH3wE1dvJN7oauYE4TYQ3ziRtg=="; //"apple";
String filter = "(&(objectclass=person)(uid=" + userId + ")(userPassword=" + userPwd + "))";
results = dirContext.search("", filter, controls);
if(results.hasMore()) {
   System.out.println("User found");
} else {
   System.out.println("User not found");
}

它有 2 个问题 - a) 在类加载的主方法中作为普通 Java 类进行测试时,它可以正常工作,但是当尝试集成到 AEM/osgi 服务类中时,它会抛出 -

javax.naming.NotContextException: Not an instance of DirContext at javax.naming.directory.InitialDirContext.getURLOrDefaultInitDirCtx(InitialDirContext.java:111) at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:267)

b) 即使在普通的 Java 类中,我也必须提供散列密码来验证,这很难集成。

String userPwd = "{SSHA}ip/DD+zUhv22NH3wE1dvJN7oauYE4TYQ3ziRtg==";//"apple";

有人可以为我提供任何可以与 osgi 集成并解决依赖关系的 maven 依赖项/库,而且我不需要提供散列密码来验证用户凭据吗?有什么方法可以解决这些问题?

【问题讨论】:

    标签: java ldap osgi aem maven-dependency


    【解决方案1】:

    第 1 步: 在项目 pom 中添加这些依赖项

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.directory.api</groupId>
        <artifactId>api-all</artifactId>
        <version>1.0.0-RC2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.mina</groupId>
        <artifactId>mina-core</artifactId>
        <version>2.1.3</version>
    </dependency>
    <dependency>
        <groupId>commons-pool</groupId>
        <artifactId>commons-pool</artifactId>
        <version>1.6</version>
    </dependency>
    <dependency>
        <groupId>antlr</groupId>
        <artifactId>antlr</artifactId>
        <version>2.7.7</version>
    </dependency>
    

    第 2 步: 将它们添加到捆绑 pom

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.directory.api</groupId>
        <artifactId>api-all</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.mina</groupId>
        <artifactId>mina-core</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-pool</groupId>
        <artifactId>commons-pool</artifactId>
    </dependency>
    <dependency>
        <groupId>antlr</groupId>
        <artifactId>antlr</artifactId>
    </dependency>
    

    第 3 步: 在插件描述的 bundle pom 中

    <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <extensions>true</extensions>
        <configuration>
            <instructions>
                <Import-Package>!net.sf.cglib.proxy, javax.inject;version=0.0.0,*</Import-Package>
                <Export-Package />
                <Sling-Model-Packages></Sling-Model-Packages>
                <Bundle-SymbolicName></Bundle-SymbolicName>
                 <Embed-Dependency>antlr, mina-core, api-all, commons-pool, commons-pool2</Embed-Dependency>
            </instructions>
        </configuration>
    </plugin>
    

    将这些用于上述插件

    <Import-Package>!net.sf.cglib.proxy</Import-Package>
    <Embed-Dependency>antlr, mina-core, api-all, commons-pool, commons-pool2</Embed-Dependency>
    

    第 4 步: 导入是具体的,仅在

    <dependency>
        <groupId>org.apache.directory.api</groupId>
        <artifactId>api-all</artifactId>
        <version>1.0.0-RC2</version>
    </dependency>
    

    被使用。因为还有一些其他依赖项提供包/类,但它们在某些时候不起作用。

    import org.apache.directory.api.ldap.model.message.SearchScope;
    import org.apache.directory.ldap.client.api.DefaultPoolableLdapConnectionFactory;
    import org.apache.directory.ldap.client.api.LdapConnectionConfig;
    import org.apache.directory.ldap.client.api.LdapConnectionPool;
    import org.apache.directory.ldap.client.template.LdapConnectionTemplate;
    import org.apache.directory.ldap.client.template.PasswordWarning;
    import org.apache.directory.ldap.client.template.exception.PasswordException;
    
    private String ldapAuthenticationApacheDsFlow(final SlingHttpServletRequest request) {
        String status = "";
        try {
            LdapConnectionConfig config = new LdapConnectionConfig();
            config.setLdapHost("localhost");
            config.setLdapPort(10389);
            config.setName("uid=admin,ou=system");
            config.setCredentials("secret");
            final DefaultPoolableLdapConnectionFactory factory = new DefaultPoolableLdapConnectionFactory(config);
            final LdapConnectionPool pool = new LdapConnectionPool(factory);
            pool.setTestOnBorrow(true);
            final LdapConnectionTemplate ldapConnectionTemplate = new LdapConnectionTemplate(pool);
            final String uid = request.getParameter("externalId");
            final String password = request.getParameter("externalPassword");
            final PasswordWarning warning = ldapConnectionTemplate.authenticate(
                    "ou=Users,dc=example,dc=com", "(uid=" + uid +")", SearchScope.SUBTREE,  password.toCharArray());
            status = "User credentials authenticated";
            if(warning != null) {
                status = status + " \n Warning!!" +warning.toString();
            }
        } catch(final PasswordException e) {
            status = e.toString();
            e.printStackTrace();
        }
        return status;
    }
    

    如果final PasswordWarning warning = 未引发错误,则用户凭据已成功验证。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-17
      • 2011-02-10
      • 1970-01-01
      • 2016-12-18
      • 2015-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多