Announcement Announcement Module
Collapse
No announcement yet.
SSL and certificates Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • SSL and certificates

    While Spring-LDAP supports SSL by using ldaps://xxxxxx:686, it appears as though I now need a certificate to be able to connect to the server. Does anybody have any suggestions about how this is implemented? I've come across references that Acegi might be able to do it, but I'm not familiar enough with the security technology to be able to say it'll work, and I can't find specific examples. I've also seen references to having the certificate held by the JVM. Any ideas would be much appreciated.

  • #2
    LDAP Certificate Initialization

    Even I am looking for the same.

    Where to initialise LDAP certificates so as to have secure connection established. ?

    In case of not using spring-LDAP, the certificate initialisation would be something like
    System.setProperty("javax.net.ssl.keyStore", s);
    System.setProperty("javax.net.ssl.keyStoreType", s1);
    System.setProperty("javax.net.ssl.keyStorePassword ", s2);
    System.setProperty("javax.net.ssl.trustStore", s3);
    System.setProperty("javax.net.ssl.trustStoreType", s4);
    System.setProperty("javax.net.ssl.trustStorePasswo rd", s5);

    If same can be done, can we extend LdapContextSource to have it. Any other way you suggest ?


    Thanks
    Santosh

    Comment


    • #3
      You can use the same system properties when using Spring-LDAP. If you'd like you could extend LdapContextSource, override afterPropertiesSet() (make sure you call super.afterPropertiesSet()), and place your initialization there.

      However, this is global system properties we are talking about. You might just as well want to supply the data to the JVM on startup (-Djavax.net.ssl.keyStore=..., etc.). The above will let you configure this stuff in you Spring Context though, so that might be a better approach.

      Comment


      • #4
        This should help. Thanks.

        Comment


        • #5
          Is there a Spring Implementation of This?

          Does anyone have a spring config file built that does this?

          Comment


          • #6
            Alright, so coming back to this topic after working out the rest of the program...

            I've followed every suggestion I could find to getting a secure AD connection. I've overridden the LdapContextSource (and updated my spring XML) to include references to the keystore, I've used the Java Control Panel to import every key I might need to every category, making my keystore 41k, and I've gone to the ActiveDirectory machine and exported the key myself, making sure IT sent me the right one. However, every connection I try to make to the SSL port gives the following exception:

            org.springframework.dao.DataRetrievalFailureExcept ion: Unable to communicate with LDAP server; nested exception is javax.naming.CommunicationException: simple bind failed: 10.1.2.11:636 [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderE xception: unable to find valid certification path to requested target]

            I'll readily admit I've learned everything I know about SSL working out this problem. If anyone has any suggestions, I'd be really grateful. Right now we've got an internal app that, if I installed it, would pass around passwords in cleartext.

            Comment


            • #7
              I don't think this is a Spring LDAP issue. I suggest you try to get ldaps working with a simple example using plain JNDI first, and then just apply the same properties and paths when you use Spring LDAP. If you still have problems with the Spring LDAP version after that, then we have something we can dig deeper into.

              Comment


              • #8
                So after coding up a replacement ContextSource, it turns out that the problem was definitely on my end. I solved it by finding out exactly where the JVM running my AppServer wanted my truststore (jre/lib/security/jssecacerts), and then following the normal code for making a connection.

                I did, however, have to construct a new LdapContextSource for authentication -- which is to be expected. To make it as Spring-like as possible, what I did was to pass my DAO singleton any values that would recur in every authentication call; namely, the secure URL. The authentication code then looks like the following:

                Code:
                    /**
                     * Try to authenticate a user
                     * @param name Username
                     * @param password Password
                     * @return True if authentication was successful.
                     */
                    public boolean authenticate(String name, String password) {
                	LdapContextSource source = new LdapContextSource();
                	source.setUrl(secureLdapUrl);
                	source.setUserName(name);
                	source.setPassword(password);
                	source.setPooled(false);
                	try {
                	    source.afterPropertiesSet();
                	    source.getReadWriteContext();
                	    return true;
                	}
                	catch(Exception e) {
                	    return false;
                	}
                    }
                The only thing I'd like to have now is a way to keep my truststore as part of the WAR so that I can move it from machine to machine without changing that machine's truststore. It seems that Java doesn't like this, no matter how many different JVM properties I try to set as environment variables. It might be a Windows/Tomcat issue. If I found a way to do that, I'd extend LdapContextSource to have support for those values, but as it stands, this suits my purposes.

                Comment


                • #9
                  Edit for the above, in case someone ends up using this to solve their own problem:

                  On another machine, Java expected the CA certs to be in jre/lib/security/cacerts instead.

                  To get the keystore/truststore where I wanted, I tried the environment variables above, both in code and by specifying options to the JVM. At least on my development environment, they wouldn't take:

                  Code:
                  System.setProperty("javax.net.ssl.keyStore", s);
                  System.setProperty("javax.net.ssl.keyStoreType", s1);
                  System.setProperty("javax.net.ssl.keyStorePassword ", s2);
                  System.setProperty("javax.net.ssl.trustStore", s3);
                  System.setProperty("javax.net.ssl.trustStoreType", s4);
                  System.setProperty("javax.net.ssl.trustStorePassword", s5);
                  It'd probably be really useful to have a SecureLdapContextSource that accepted options like certificates, but for the time being I've solved my issue just by accepting defaults. I've got a mostly-written SecureLdapContextSource of my own, but, yeah, without the ability to specify truststore paths, it's not at all useful.

                  Comment


                  • #10
                    I've tried the code below and it works except if a blank password is supplied. In this case the authenticate message returns true - not what I would have expected. It's easy to workaround, i.e. fail if a blank password gets passed in. But does anyone understand why a blank password passes authentication and how to prevent it? Thanks

                    PS: Sorry, I am a newbie and don't know how to format the code snippet.

                    /**
                    * Try to authenticate a user
                    * @param name Username
                    * @param password Password
                    * @return True if authentication was successful.
                    */
                    public boolean authenticate(String name, String password) {
                    LdapContextSource source = new LdapContextSource();
                    source.setUrl(secureLdapUrl);
                    source.setUserName(name);
                    source.setPassword(password);
                    source.setPooled(false);
                    try {
                    source.afterPropertiesSet();
                    source.getReadWriteContext();
                    return true;
                    }
                    catch(Exception e) {
                    return false;
                    }
                    }

                    Comment


                    • #11
                      You know, I ran into the same issue -- is your LDAP server allowing anonymous connections at all? I think if you fail to supply a password it defaults to anonymous bind. It could also be a bug. I just added the Validator.

                      Comment

                      Working...
                      X