I am trying to configure LDAPS on Elytron on Wildfly 25 and I do not know what I'm missing.
I always get this error because the server rejects non SSL connections:
2021-10-12 09:54:53,597 DEBUG [org.wildfly.security] (default task-1) Could not create [class javax.naming.ldap.InitialLdapContext]. Failed to connect to LDAP server.: javax.naming.CommunicationException: LDAP.example:636 [Root exception is java.net.SocketTimeoutException: Read timed out]
at java.naming/com.sun.jndi.ldap.Connection.<init>(Connection.java:253)
at java.naming/com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137)
at java.naming/com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1616)
I guess I'm missing something in the dir-context in standalone.xml, any ideas?
<dir-contexts>
<dir-context name="ldap-connection" url="LDAPS://LDAP.example:636" authentication-level="simple" principal="CN=......." ssl-context="LocalhostSslContext">
<credential-reference clear-text="pass"/>
</dir-context>
</dir-contexts>
CodePudding user response:
The issue was the way I was using the truststore, after I reconfigured it like so, it worked. Full example: https://github.com/wildfly/wildfly-core/blob/main/elytron/src/test/resources/org/wildfly/extension/elytron/ldap.xml
Extract:
<subsystem xmlns="urn:wildfly:elytron:14.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
...
<tls>
<key-stores>
...
<key-store name="TrustStore">
<credential-reference clear-text="secret" />
<implementation type="JKS" />
<file path="truststore.jks" relative-to="jboss.server.config.dir" />
</key-store>
</key-stores>
...
<trust-managers>
<trust-manager name="TrustManager" key-store="TrustStore" />
</trust-managers>
...
<client-ssl-contexts>
<client-ssl-context name="LdapSslContext" protocols="SSLv2 SSLv3 TLSv1 TLSv1.3 TLSv1.2 TLSv1.1" trust-manager="TrustManager" />
</client-ssl-contexts>
</tls>
<dir-contexts>
<dir-context name="ldap-connection" url="ldaps://ldap.example:636" principal="CN=user...." ssl-context="LdapSslContext">
<credential-reference clear-text="secret" />
</dir-context>
</dir-contexts>
</subsystem>
CodePudding user response:
An example of usage:
<subsystem xmlns="urn:wildfly:elytron:1.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
...
<security-realms>
...
<ldap-realm name="ldap-realm" dir-context="ldap-connection" direct-verification="true">
<identity-mapping rdn-identifier="uid" search-base-dn="ou=users,dc=group-to-principal,dc=wildfly,dc=org">
<attribute-mapping>
<attribute from="uid" to="Roles" filter="(uniqueMember={1})" filter-base-dn="ou=groups,dc=group-to-principal,dc=wildfly,dc=org"/>
</attribute-mapping>
</identity-mapping>
</ldap-realm>
</security-realms>
...
<dir-contexts>
<dir-context name="ldap-connection" url="ldap://localhost:10389" principal="uid=admin,ou=system">
<credential-reference clear-text="secret"/>
</dir-context>
</dir-contexts>
</subsystem>
For reference: https://docs.jboss.org/author/display/WFLY/LDAP Based Authentication Migration.html
-- Updated --
Reference ldap.xml for setting up LDAP for testing that could be usefull.
<subsystem xmlns="urn:wildfly:elytron:14.0" initial-providers="elytron">
<authentication-client>
<authentication-configuration name="ldapAuthConfig" authentication-name="uid=server,dc=users,dc=elytron,dc=wildfly,dc=org">
<credential-reference clear-text="serverPassword"/>
</authentication-configuration>
<authentication-context name="ldapAuthContext">
<match-rule match-host="localhost" match-protocol="ldaps" authentication-configuration="ldapAuthConfig" ssl-context="LdapSslContext"/>
<match-rule match-host="localhost" match-protocol="ldap" authentication-configuration="ldapAuthConfig"/>
</authentication-context>
</authentication-client>
<providers>
<provider-loader name="elytron" class-names="org.wildfly.security.WildFlyElytronProvider" />
</providers>
<security-realms>
<ldap-realm name="LdapRealm" dir-context="DirContextSsl">
<identity-mapping filter-name="(|(objectclass=referral)(uid={0}))" iterator-filter="(|(objectclass=referral)(uid=*))" new-identity-parent-dn="dc=users,dc=elytron,dc=wildfly,dc=org" rdn-identifier="uid" search-base-dn="dc=users,dc=elytron,dc=wildfly,dc=org" use-recursive-search="true">
<attribute-mapping>
<attribute to="userDn"/>
<attribute from="uid" to="userName"/>
<attribute from="cn" to="firstName"/>
<attribute from="sn"/>
<attribute from="telephoneNumber" to="phones"/>
<attribute filter="(&(objectClass=groupOfNames)(member={1}))" filter-base-dn="dc=elytron,dc=wildfly,dc=org" to="rolesDn"/>
<attribute filter="(&(objectClass=groupOfNames)(member={1}))" filter-base-dn="dc=elytron,dc=wildfly,dc=org" to="rolesRecRdnCn" role-recursion="2" extract-rdn="CN"/>
<attribute filter="(&(objectClass=groupOfNames)(member={1}))" filter-base-dn="dc=elytron,dc=wildfly,dc=org" to="rolesCn" extract-rdn="CN"/>
<attribute filter="(&(objectClass=groupOfNames)(member={1}))" filter-base-dn="dc=elytron,dc=wildfly,dc=org" from="description" to="rolesDescription" role-recursion="2"/>
<attribute filter="(&(objectClass=organizationalRole)(description={0}))" filter-base-dn="dc=elytron,dc=wildfly,dc=org" from="street" to="rolesByName" role-recursion="2" role-recursion-name="postalCode"/>
<attribute reference="memberOf" from="description" to="memberOfDescription" role-recursion="5"/>
<attribute reference="memberOf" to="memberOfDn" role-recursion="3"/>
</attribute-mapping>
<new-identity-attributes>
<attribute name="objectClass" value="top inetOrgPerson person organizationalPerson otpToken"/>
<attribute name="sn" value="BlankSurname"/>
<attribute name="cn" value="BlankCommonName"/>
</new-identity-attributes>
<user-password-mapper from="userPassword" writable="true"/>
<otp-credential-mapper algorithm-from="otpAlgorithm" hash-from="otpHash" seed-from="otpSeed" sequence-from="otpSequence"/>
<x509-credential-mapper digest-from="x509digest" certificate-from="usercertificate" subject-dn-from="x509subject" serial-number-from="x509serialNumber" />
</identity-mapping>
</ldap-realm>
<ldap-realm name="LdapRealmDirectVerification" dir-context="DirContextSsl" direct-verification="true" allow-blank-password="true">
<identity-mapping filter-name="(|(objectclass=referral)(uid={0}))" iterator-filter="(uid=*)" new-identity-parent-dn="dc=users,dc=elytron,dc=wildfly,dc=org" rdn-identifier="uid" search-base-dn="dc=users,dc=elytron,dc=wildfly,dc=org" use-recursive-search="true">
</identity-mapping>
</ldap-realm>
<ldap-realm name="LdapRealmCharset" dir-context="DirContextSsl" hash-charset="GB2312">
<identity-mapping filter-name="(|(objectclass=referral)(uid={0}))" iterator-filter="(|(objectclass=referral)(uid=*))" new-identity-parent-dn="dc=users,dc=elytron,dc=wildfly,dc=org" rdn-identifier="uid" search-base-dn="dc=users,dc=elytron,dc=wildfly,dc=org" use-recursive-search="true" >
<attribute-mapping>
<attribute to="userDn"/>
<attribute from="uid" to="userName"/>
<attribute from="cn" to="firstName"/>
<attribute from="sn"/>
</attribute-mapping>
<user-password-mapper from="userPassword" writable="true"/>
</identity-mapping>
</ldap-realm>
<ldap-realm name="LdapRealmEncodingCharset" dir-context="DirContextSsl" hash-charset="GB2312" hash-encoding="hex">
<identity-mapping filter-name="(|(objectclass=referral)(uid={0}))" iterator-filter="(|(objectclass=referral)(uid=*))" new-identity-parent-dn="dc=users,dc=elytron,dc=wildfly,dc=org" rdn-identifier="uid" search-base-dn="dc=users,dc=elytron,dc=wildfly,dc=org" use-recursive-search="true" >
<attribute-mapping>
<attribute to="userDn"/>
<attribute from="uid" to="userName"/>
<attribute from="cn" to="firstName"/>
<attribute from="sn"/>
</attribute-mapping>
<user-password-mapper from="userPassword" writable="true"/>
</identity-mapping>
</ldap-realm>
</security-realms>
<tls>
<key-stores>
<key-store name="ElytronCaTruststore" >
<credential-reference clear-text="Elytron"/>
<implementation type="JKS" />
<file path="ca.truststore" relative-to="jboss.server.config.dir"/>
</key-store>
<ldap-key-store dir-context="DirContextSsl" name="LdapKeyStoreMinimal">
<search path="ou=keystore,dc=elytron,dc=wildfly,dc=org"/>
</ldap-key-store>
<ldap-key-store dir-context="DirContextSsl" name="LdapKeyStoreMaximal">
<new-item-template new-item-path="ou=keystore,dc=elytron,dc=wildfly,dc=org" new-item-rdn="cn">
<attribute name="objectClass" value="top inetOrgPerson"/>
<attribute name="sn" value="NewKeyStoreItem"/>
</new-item-template>
<search path="dc=elytron,dc=wildfly,dc=org" recursive="true" time-limit="1000" filter-alias="(&(objectClass=inetOrgPerson)(sn={0}))"
filter-certificate="(&(objectClass=inetOrgPerson)(usercertificate={0}))" filter-iterate="(sn=serenity*)"/>
<attribute-mapping alias-attribute="sn" certificate-attribute="usercertificate" certificate-chain-attribute="userSMIMECertificate" certificate-chain-encoding="PKCS7" certificate-type="X.509"/>
</ldap-key-store>
</key-stores>
<key-managers>
<key-manager name="LdapKeyManager" key-store="LdapKeyStoreMaximal">
<credential-reference clear-text="Elytron"/>
</key-manager>
</key-managers>
<trust-managers>
<trust-manager key-store="ElytronCaTruststore" name="ElytronTrustManager"/>
</trust-managers>
<client-ssl-contexts>
<client-ssl-context name="LdapSslContext" protocols="SSLv2 SSLv3 TLSv1 TLSv1.3 TLSv1.2 TLSv1.1" trust-manager="ElytronTrustManager"/>
</client-ssl-contexts>
</tls>
<dir-contexts>
<dir-context authentication-level="none" authentication-context="ldapAuthContext" name="DirContextInsecure" url="ldap://localhost:11391/"/>
<dir-context name="DirContextSsl" authentication-context="ldapAuthContext" referral-mode="throw" url="ldaps://localhost:11391/" connection-timeout="6000" read-timeout="10000">
<properties>
<property name="java.naming.dns.url" value="dns://dnsserver/wiz.com"/>
</properties>
</dir-context>
<dir-context name="DirContextSslCredential" url="ldaps://localhost:11391/" principal="uid=server,dc=users,dc=elytron,dc=wildfly,dc=org" ssl-context="LdapSslContext">
<credential-reference clear-text="serverPassword"/>
</dir-context>
</dir-contexts>
</subsystem>