How to use a custom ssh key location with Spring Cloud Config

后端 未结 3 753
难免孤独
难免孤独 2021-02-14 23:25

I am trying to setup a Spring Cloud Config server that uses a custom location for the ssh private key. The reason i need to specify a custom location for the key is because the

相关标签:
3条回答
  • 2021-02-14 23:43

    The FixedSshSessionFactory solution of @Jeffrey Zampieron is good. However it won't work if packaging the spring boot app as a fat jar.

    Polish it a bit for working with fat jar,

    /**
     * @file FixedSshSessionFactory.java
     * @date Aug 23, 2016 2:16:11 PM
     * @author jzampieron
     */
    
    import com.jcraft.jsch.JSch;
    import com.jcraft.jsch.JSchException;
    import com.jcraft.jsch.Session;
    import lombok.extern.slf4j.Slf4j;
    import org.eclipse.jgit.transport.JschConfigSessionFactory;
    import org.eclipse.jgit.transport.OpenSshConfig.Host;
    import org.eclipse.jgit.util.FS;
    import org.springframework.util.StreamUtils;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URL;
    
    /**
     * Short Desc Here.
     *
     * @author jzampieron
     */
    @Slf4j
    public class FixedSshSessionFactory extends JschConfigSessionFactory {
    
        protected URL[] identityKeyURLs;
    
        /**
         * @param url
         */
        public FixedSshSessionFactory(URL... identityKeyURLs) {
            this.identityKeyURLs = identityKeyURLs;
        }
    
        /* (non-Javadoc)
         * @see org.eclipse.jgit.transport.JschConfigSessionFactory#configure(org.eclipse.jgit.transport.OpenSshConfig.Host, com.jcraft.jsch.Session)
         */
        @Override
        protected void configure(Host hc, Session session) {
            // nothing special needed here.
        }
    
        /* (non-Javadoc)
         * @see org.eclipse.jgit.transport.JschConfigSessionFactory#getJSch(org.eclipse.jgit.transport.OpenSshConfig.Host, org.eclipse.jgit.util.FS)
         */
        @Override
        protected JSch getJSch(Host hc, FS fs) throws JSchException {
            JSch jsch = super.getJSch(hc, fs);
            // Clean out anything 'default' - any encrypted keys
            // that are loaded by default before this will break.
            jsch.removeAllIdentity();
            int count = 0;
            for (final URL identityKey : identityKeyURLs) {
                try (InputStream stream = identityKey.openStream()) {
                    jsch.addIdentity("key" + ++count, StreamUtils.copyToByteArray(stream), null, null);
                } catch (IOException e) {
                    logger.error("Failed to load identity " + identityKey.getPath());
                }
            }
            return jsch;
        }
    
    
    }
    
    0 讨论(0)
  • 2021-02-14 23:53

    After reading a lot more code... I found a relatively simple work around to allow you to set whatever SSH keys you want.

    First: Create a class as follows:

    /**
     * @file FixedSshSessionFactory.java 
     * 
     * @date Aug 23, 2016 2:16:11 PM 
     * @author jzampieron
     */
    
    import org.eclipse.jgit.transport.JschConfigSessionFactory;
    import org.eclipse.jgit.transport.OpenSshConfig.Host;
    import org.eclipse.jgit.util.FS;
    
    import com.jcraft.jsch.JSch;
    import com.jcraft.jsch.JSchException;
    import com.jcraft.jsch.Session;
    
    /**
     * Short Desc Here.
     * 
     * @author jzampieron
     *
     */
    public class FixedSshSessionFactory extends JschConfigSessionFactory
    {
    
       protected String[] identityKeyPaths;
    
       /**
        * @param string
        */
       public FixedSshSessionFactory( String... identityKeyPaths )
       {
          this.identityKeyPaths = identityKeyPaths;
       }
    
       /* (non-Javadoc)
        * @see org.eclipse.jgit.transport.JschConfigSessionFactory#configure(org.eclipse.jgit.transport.OpenSshConfig.Host, com.jcraft.jsch.Session)
        */
       @Override
       protected void configure( Host hc, Session session )
       {
          // nothing special needed here.
       }
    
       /* (non-Javadoc)
        * @see org.eclipse.jgit.transport.JschConfigSessionFactory#getJSch(org.eclipse.jgit.transport.OpenSshConfig.Host, org.eclipse.jgit.util.FS)
        */
       @Override
       protected JSch getJSch( Host hc, FS fs ) throws JSchException
       {
          JSch jsch = super.getJSch( hc, fs );
          // Clean out anything 'default' - any encrypted keys
          // that are loaded by default before this will break.
          jsch.removeAllIdentity();
          for( final String identKeyPath : identityKeyPaths )
          {
             jsch.addIdentity( identKeyPath );
          }
          return jsch;
       }
    
    
    }
    

    Then register it with jgit:

    ...
    import org.eclipse.jgit.transport.SshSessionFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.config.server.EnableConfigServer;
    
    @SpringBootApplication
    @EnableConfigServer
    public class ConfigserverApplication 
    {
    
        public static void main(String[] args) {
           URL res = ConfigserverApplication.class.getClassLoader().getResource( "keys/id_rsa" );
           String path = res.getPath();
           SshSessionFactory.setInstance( new FixedSshSessionFactory( path ) );
    
           SpringApplication.run(ConfigserverApplication.class, args);
        }
    
    }
    

    For this example I'm storing the keys in the src/main/resources/keys folder and I'm using the class loader to get at them.

    The removeAllIdentities is important b/c JSch was loading my default ssh key before the one I specified and then Spring Cloud was crashing out b/c its encrypted.

    This allowed me to successfully authenticate with bitbucket.

    0 讨论(0)
  • 2021-02-14 23:58

    I am having a similar problem because my default SSH key is encrypted with a password and therefore doesn't "just work", which makes sense because this is a head-less setup.

    I went source-diving into Spring Cloud Config, org.eclipse.jgit and eventually ended up in com.jcraft.jsch. The short answer is that neither JGit nor Spring Cloud expose an obvious way to do this.

    JSch clearly supports this feature within a JSch() instance, but you can't get at it from the Spring Cloud level. At least not that I could find in a hour or so of looking.

    0 讨论(0)
提交回复
热议问题