无法在spring-ldap客户端和apached

时间:2017-07-21 08:01:11

标签: tls1.2 spring-ldap apacheds

我的客户端代码已使用LDAP协议针对嵌入式ApacheDS 1.5.5成功测试。在使用Apache DS 2.0.0-M23的端到端测试中,我成功地使用OpenLDAP建立了LDAPS连接。但是,我在使用基于Java的spring-ldap建立LDAPS连接时遇到了问题。我的代码基于spring-ldap。任何深入挖掘TLS或LDAPS的技巧都会受到赞赏。

版本

Oracle JDK:带有JCE Unlimited Strength Jurisdiction Policy Files的Java版“1.8.0_92”。

Spring-Ldap版本:2.3.1.RELEASE

Spring Version:4.3.2.RELEASE

Apache DS版本:2.0.0-M23部署在Docker容器中。

创建公共证书和私钥

基于:Apache DS - Enable SSL

导出LDAP服务器上使用的证书:

[jlee@iel-jlee-lt1 security]$ keytool -genkey -keyalg "RSA" -dname "cn=tangotelecom.com, ou=dev, o=tangotelecom, c=IE" -alias tangotelecom -keystore tangotelecom.ks -storepass secret -validity 730
Enter key password for <tangotelecom>
(RETURN if same as keystore password):
[jlee@iel-jlee-lt1 security]$ keytool -list -keystore tangotelecom.ks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

tangotelecom, 06-Jul-2017, PrivateKeyEntry,
Certificate fingerprint (SHA1): 56:0C:5C:7A:DD:97:F1:4D:A2:B6:D1:2B:EC:D0:11:4A:B1:79:F3:CF

[jlee@iel-jlee-lt1 security]$ keytool -export -keystore tangotelecom.ks -alias tangotelecom -file tangotelecom.cer
Enter keystore password:
Certificate stored in file <tangotelecom.cer>

将公共证书导入cacerts文件以供客户使用:

[tango@iel-dev-tfsr-vm2 16:30:57 john]$ sudo keytool -import -trustcacerts -keystore /opt/java8/jre/lib/security/cacerts -storepass changeit -noprompt -alias tangotelecom -file /home/tango/john/tangotelecom.cer
[sudo] password for tango:
Certificate was added to keystore

TLS DEBUG

Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false

%% No cached client session

*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1500415942 bytes = { 188, 130, 166, 249, 170, 224, 174, 199, 55, 88, 195, 144, 45, 147, 143, 225, 45, 223, 30, 91, 195, 43, 83, 241, 197, 150, 41, 54 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension server_name, server_name: [type=host_name (0), value=tangotelecom.com]
***
Thread-8, WRITE: TLSv1.2 Handshake, length = 260

Thread-8, READ: TLSv1.2 Handshake, length = 1257
*** ServerHello, TLSv1.2
RandomCookie:  GMT: 1500416088 bytes = { 2, 142, 226, 16, 107, 183, 43, 206, 220, 107, 239, 113, 204, 172, 241, 154, 87, 185, 49, 94, 163, 9, 187, 229, 53, 41, 78, 254 }
Session ID:  {89, 111, 136, 88, 183, 123, 76, 181, 211, 21, 149, 160, 218, 222, 226, 244, 139, 145, 143, 72, 3, 7, 184, 96, 34, 155, 76, 54, 60, 117, 215, 179}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
%% Initialized:  [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
** TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
*** Certificate chain

chain [0] = [
[
  Version: V3
  Subject: CN=tangotelecom.com, OU=dev, O=tangotelecom, C=IE
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  modulus: 22980180191390060691645191877521292031505114546367033225089259442617005098274762521554359946742065878415849288262185146512594592923140681158742168163906077539516435863146152603064701157961527256158756559349035940810739650464273192076580461817700601005238106947505955687153311906740088488389957201959449147054853786865353874624664733186248186940444317144962411956375681259742751499094173934719877768378414836567412356975874572170519318320962628133692056724599530776533547533308568698574604059550372476889963449850184432248569481738632894450321061794712987632959422197533269207285625710288277728878653909213375498707927
  public exponent: 65537
  Validity: [From: Thu Jul 06 15:48:29 IST 2017,
               To: Sat Jul 06 15:48:29 IST 2019]
  Issuer: CN=tangotelecom.com, OU=dev, O=tangotelecom, C=IE
  SerialNumber: [    6dce9c09]

Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E1 BA 73 DD F2 41 0F CF   BD 4B 9B 99 D7 01 BD 2F ..s..A...K...../
0010: 7D 9A 31 B7                                        ..1.
]
]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 2C DB 4A FA BD A9 1D 29   C0 0A 8F 69 7F 39 11 DA ,.J....)...i.9..
0010: 4A 21 0D 66 53 A5 03 CC   33 AB 4D E6 C1 55 75 E3 J!.fS...3.M..Uu.
0020: 8C 22 C6 F9 05 26 27 EF   BC C0 CB D8 12 3C 7C 95 ."...&'......<..
0030: 9B 56 88 06 71 CA 3A 17   99 6A 23 53 E9 CC 9B 05 .V..q.:..j#S....
0040: E6 85 89 25 DC CF 95 3A   41 62 5D 0C CE E9 0F D4 ...%...:Ab].....
0050: 7E 0E B6 4D CE 5A 49 F4   BB DD 9A 85 55 C1 39 0E ...M.ZI.....U.9.
0060: 0F B4 34 44 05 64 E5 F3   F0 4A 5C 40 91 2C 1E B3 ..4D.d...J\@.,..
0070: 39 D1 56 71 C2 83 48 CA   31 E5 44 60 B4 65 8D BA 9.Vq..H.1.D`.e..
0080: 70 65 7C 93 B8 84 E4 60   38 EA C7 21 7D AF 30 BD pe.....`8..!..0.
0090: 6F D5 CC 04 DA 33 E8 14   DA E8 AC BA 6A 03 5E C9 o....3......j.^.
00A0: 56 DC 78 07 FB 44 DB A8   B2 4D CE 30 CB 56 7E 6B V.x..D...M.0.V.k
00B0: F6 CE BF 3D B4 77 21 33   53 BA D8 E2 B1 B9 F4 95 ...=.w!3S.......
00C0: 05 7E FB B4 3A CF 09 29   10 B1 4E CF 38 AF 81 D6 ....:..)..N.8...
00D0: 6B DD 60 51 1C 04 27 41   71 98 07 DE B9 82 4A 1A k.`Q..'Aq.....J.
00E0: 0D F7 04 6D 09 F4 E7 1F   FE 2C 07 41 EE 84 F3 F6 ...m.....,.A....
00F0: 1A F4 62 87 3D 94 A6 5D   FD 3D 8B EE 1B A1 5B 52 ..b.=..].=....[R

]
***
Found trusted certificate:
[
[
  Version: V3
  Subject: CN=tangotelecom.com, OU=dev, O=tangotelecom, C=IE
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  modulus: 22980180191390060691645191877521292031505114546367033225089259442617005098274762521554359946742065878415849288262185146512594592923140681158742168163906077539516435863146152603064701157961527256158756559349035940810739650464273192076580461817700601005238106947505955687153311906740088488389957201959449147054853786865353874624664733186248186940444317144962411956375681259742751499094173934719877768378414836567412356975874572170519318320962628133692056724599530776533547533308568698574604059550372476889963449850184432248569481738632894450321061794712987632959422197533269207285625710288277728878653909213375498707927
  public exponent: 65537
  Validity: [From: Thu Jul 06 15:48:29 IST 2017,
               To: Sat Jul 06 15:48:29 IST 2019]
  Issuer: CN=tangotelecom.com, OU=dev, O=tangotelecom, C=IE
  SerialNumber: [    6dce9c09]

Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E1 BA 73 DD F2 41 0F CF   BD 4B 9B 99 D7 01 BD 2F ..s..A...K...../
0010: 7D 9A 31 B7                                        ..1.
]
]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 2C DB 4A FA BD A9 1D 29   C0 0A 8F 69 7F 39 11 DA ,.J....)...i.9..
0010: 4A 21 0D 66 53 A5 03 CC   33 AB 4D E6 C1 55 75 E3 J!.fS...3.M..Uu.
0020: 8C 22 C6 F9 05 26 27 EF   BC C0 CB D8 12 3C 7C 95 ."...&'......<..
0030: 9B 56 88 06 71 CA 3A 17   99 6A 23 53 E9 CC 9B 05 .V..q.:..j#S....
0040: E6 85 89 25 DC CF 95 3A   41 62 5D 0C CE E9 0F D4 ...%...:Ab].....
0050: 7E 0E B6 4D CE 5A 49 F4   BB DD 9A 85 55 C1 39 0E ...M.ZI.....U.9.
0060: 0F B4 34 44 05 64 E5 F3   F0 4A 5C 40 91 2C 1E B3 ..4D.d...J\@.,..
0070: 39 D1 56 71 C2 83 48 CA   31 E5 44 60 B4 65 8D BA 9.Vq..H.1.D`.e..
0080: 70 65 7C 93 B8 84 E4 60   38 EA C7 21 7D AF 30 BD pe.....`8..!..0.
0090: 6F D5 CC 04 DA 33 E8 14   DA E8 AC BA 6A 03 5E C9 o....3......j.^.
00A0: 56 DC 78 07 FB 44 DB A8   B2 4D CE 30 CB 56 7E 6B V.x..D...M.0.V.k
00B0: F6 CE BF 3D B4 77 21 33   53 BA D8 E2 B1 B9 F4 95 ...=.w!3S.......
00C0: 05 7E FB B4 3A CF 09 29   10 B1 4E CF 38 AF 81 D6 ....:..)..N.8...
00D0: 6B DD 60 51 1C 04 27 41   71 98 07 DE B9 82 4A 1A k.`Q..'Aq.....J.
00E0: 0D F7 04 6D 09 F4 E7 1F   FE 2C 07 41 EE 84 F3 F6 ...m.....,.A....
00F0: 1A F4 62 87 3D 94 A6 5D   FD 3D 8B EE 1B A1 5B 52 ..b.=..].=....[R

]
*** ECDH ServerKeyExchange
Signature Algorithm SHA512withRSA
Server key: Sun EC public key, 256 bits
  public x coord: 65335040139868512120179408985992060136049248034231183953393366519969264579494
  public y coord: 99476183036375747385598841109418769282434814800382623908755157948061455956677
  parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)
*** ServerHelloDone
*** ECDHClientKeyExchange
ECDH Public value:  { 4, 6, 89, 131, 180, 42, 189, 111, 119, 56, 149, 20, 50, 182, 23, 83, 192, 173, 201, 60, 5, 132, 156, 221, 3, 44, 131, 63, 1, 166, 164, 34, 3, 56, 203, 122, 234, 174, 144, 123, 135, 210, 236, 219, 230, 153, 161, 126, 189, 78, 72, 8, 98, 201, 57, 28, 243, 18, 56, 113, 156, 118, 238, 160, 238 }
Thread-8, WRITE: TLSv1.2 Handshake, length = 70
SESSION KEYGEN:
PreMaster Secret:
0000: BD 2B CF E4 3E 6A 0D 32   97 16 67 3E 5A 46 CD CD .+..>j.2..g>ZF..
0010: CA 52 5B 89 28 43 45 35   09 89 74 1F B6 D9 02 7B .R[.(CE5..t.....
CONNECTION KEYGEN:
Client Nonce:
0000: 59 6F 88 C6 BC 82 A6 F9   AA E0 AE C7 37 58 C3 90 Yo..........7X..
0010: 2D 93 8F E1 2D DF 1E 5B   C3 2B 53 F1 C5 96 29 36 -...-..[.+S...)6
Server Nonce:
0000: 59 6F 88 58 02 8E E2 10   6B B7 2B CE DC 6B EF 71 Yo.X....k.+..k.q
0010: CC AC F1 9A 57 B9 31 5E   A3 09 BB E5 35 29 4E FE ....W.1^....5)N.
Master Secret:
0000: 44 0B B5 4E 2C 69 E1 68   85 F3 21 08 1A 75 F8 01 D..N,i.h..!..u..
0010: 33 1A 6B 3A 55 7B D3 65   F8 D6 3C BD 10 40 B2 E4 3.k:U..e..<..@..
0020: A2 BC 8A 31 1F 41 9E C6   FC A4 40 F7 2F B2 59 3F ...1.A....@./.Y?
Client MAC write Secret:
0000: C0 97 F8 99 19 72 9D 18   63 FD CD 8C 64 23 BC B1 .....r..c...d#..
0010: 7B 58 D4 52 9C 71 E6 42   0A 20 ED 53 31 5F 27 A7  .X.R.q.B. .S1_'.
0020: 47 3E EA 1D AA 12 CA AA   14 1B 63 98 E0 1B AD F8 G>........c.....
Server MAC write Secret:
0000: 98 BE 74 96 5D 1B 69 7D   96 0D 83 25 C3 D6 24 B0 ..t.].i....%..$.
0010: 57 15 08 62 A6 69 E3 DA   77 3D 73 A3 E6 D9 A8 7A W..b.i..w=s....z
0020: 46 E0 D2 49 ED 53 86 45   18 97 92 C3 C9 61 45 4E F..I.S.E.....aEN
Client write key:
0000: 27 67 0E 91 81 3A 6A 5B   87 78 1D E0 EB 6B C7 AE 'g...:j[.x...k..
0010: B8 78 13 9F 6F C2 8B 4E   AC 3F 01 07 BC 5C 9B 0E .x..o..N.?...\..
Server write key:
0000: 3E D2 EE 99 D4 53 84 15   C6 D6 66 5D A8 A5 40 7C >....S....f]..@.
0010: 65 BB 8E A8 DF F7 B8 22   6C EF 6C 82 26 63 7D 99 e......"l.l.&c..
... no IV derived for this protocol
Thread-8, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 101, 250, 185, 66, 42, 146, 49, 129, 108, 63, 34, 156 }
***
Thread-8, WRITE: TLSv1.2 Handshake, length = 96
Thread-8, READ: TLSv1.2 Change Cipher Spec, length = 1
Thread-8, READ: TLSv1.2 Handshake, length = 96
*** Finished
verify_data:  { 221, 251, 110, 51, 35, 95, 63, 112, 169, 189, 61, 120 }
***
%% Cached client session: [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
ForkJoinPool.commonPool-worker-2, WRITE: TLSv1.2 Application Data, length = 96
Thread-8, handling exception: javax.net.ssl.SSLException: Unsupported record version Unknown-38.2
%% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
Thread-8, SEND TLSv1.2 ALERT:  fatal, description = unexpected_message
Thread-8, WRITE: TLSv1.2 Alert, length = 80
Thread-8, called closeSocket()
Thread-8, called close()
Thread-8, called closeInternal(true)

Spring LDAP客户端配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:ldap="http://www.springframework.org/schema/ldap"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd">

    <context:property-placeholder location="classpath:application.properties"/>
    <bean id="ldapAuthenticationStrategy" class="org.springframework.ldap.core.support.DefaultTlsDirContextAuthenticationStrategy">
        <property name="shutdownTlsGracefully" value="true"/>
    </bean>
    <ldap:context-source url="${ldap.primary.url}, ${ldap.secondary.url}"
                         username="${ldap.userDn}"
                         password="${ldap.password}"
                         base="${ldap.base}"
                         referral="follow"
                         native-pooling="false"
                         authentication-strategy-ref="ldapAuthenticationStrategy">
    </ldap:context-source>
    <ldap:ldap-template id="ldapTemplate" context-source-ref="contextSource" time-limit="5000"/>
</beans>

代码

public class TangoLdapClient {
    static final String UID = "uid";

    private final LdapTemplate ldapTemplate;

    /**
     * Constructor.
     * @param ldapTemplate {@link LdapTemplate}.
     */
    public TangoLdapClient(@NonNull final LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
    }

    /**
     * Authenticate with username and password.
     * @param username username.
     * @param password password.
     * @throws EmptyResultDataAccessException in the case that the username is not found, and therefore cannot be mapped to dn.
     * @throws AuthenticationException in the case where the password doesn't match.
     */
    public void authenticate(@NonNull final String username, @NonNull final String password)
            throws EmptyResultDataAccessException, AuthenticationException {
        Preconditions.checkArgument(StringUtils.isNotBlank(username));
        ldapTemplate.authenticate(buildFindUserFromUserName(username), password,
            (ctx, ldapEntryIdentification) -> wrappedMapper(ctx, ldapEntryIdentification));
    }

    private LdapQuery buildFindUserFromUserName(final String username) {
        return query().where(UID).is(username);
    }

    private static DirContextOperations wrappedMapper(final DirContext ctx,
                                                      final LdapEntryIdentification ldapEntryIdentification) {
        try {
            return (DirContextOperations) ctx.lookup(ldapEntryIdentification.getRelativeName());
        } catch (NamingException e) {
            throw new RuntimeException("Failed to lookup " + ldapEntryIdentification.getRelativeName(), e);
        }
    }
}

0 个答案:

没有答案