Connecting to remote URL which requires authentication using Java

前端 未结 12 2185
庸人自扰
庸人自扰 2020-11-22 12:59

How do I connect to a remote URL in Java which requires authentication. I\'m trying to find a way to modify the following code to be able to programatically provide a userna

12条回答
  •  攒了一身酷
    2020-11-22 13:48

    I'd like to provide an answer for the case that you do not have control over the code that opens the connection. Like I did when using the URLClassLoader to load a jar file from a password protected server.

    The Authenticator solution would work but has the drawback that it first tries to reach the server without a password and only after the server asks for a password provides one. That's an unnecessary roundtrip if you already know the server would need a password.

    public class MyStreamHandlerFactory implements URLStreamHandlerFactory {
    
        private final ServerInfo serverInfo;
    
        public MyStreamHandlerFactory(ServerInfo serverInfo) {
            this.serverInfo = serverInfo;
        }
    
        @Override
        public URLStreamHandler createURLStreamHandler(String protocol) {
            switch (protocol) {
                case "my":
                    return new MyStreamHandler(serverInfo);
                default:
                    return null;
            }
        }
    
    }
    
    public class MyStreamHandler extends URLStreamHandler {
    
        private final String encodedCredentials;
    
        public MyStreamHandler(ServerInfo serverInfo) {
            String strCredentials = serverInfo.getUsername() + ":" + serverInfo.getPassword();
            this.encodedCredentials = Base64.getEncoder().encodeToString(strCredentials.getBytes());
        }
    
        @Override
        protected URLConnection openConnection(URL url) throws IOException {
            String authority = url.getAuthority();
            String protocol = "http";
            URL directUrl = new URL(protocol, url.getHost(), url.getPort(), url.getFile());
    
            HttpURLConnection connection = (HttpURLConnection) directUrl.openConnection();
            connection.setRequestProperty("Authorization", "Basic " + encodedCredentials);
    
            return connection;
        }
    
    }
    

    This registers a new protocol my that is replaced by http when credentials are added. So when creating the new URLClassLoader just replace http with my and everything is fine. I know URLClassLoader provides a constructor that takes an URLStreamHandlerFactory but this factory is not used if the URL points to a jar file.

提交回复
热议问题