【问题标题】:Per-Proxy Authentication in JavaJava中的每个代理身份验证
【发布时间】:2015-04-01 17:11:18
【问题描述】:

我正在尝试在我的 Java 应用程序中支持经过身份验证的代理。我的理解是java.net.Proxy类不支持认证,需要自己处理认证。

我创建了 java.net.Proxy 类的一个子类,它接受两个附加参数,用户名和密码。

实现 HTTP 代理身份验证非常简单,getHttpProxyAuthenticationHeader 方法简单地返回 base64 编码的身份验证信息,传递给 HttpUrlConnection 或类似的。

不过,我在使用 Sock 代理时遇到了问题。我找不到任何有关向 Socks 服务器发送身份验证的文档。我不确定是否需要在我的类中使用 authenticateSocksProxy(OutputStream stream) 等方法实现 SOCKS 身份验证协议,然后调用

authedProxy.authenticateSocksProxy(outputstream);

在使用套接字之前

outputstream.writeBytes(myData.getBytes());

另一种选择是返回身份验证数据的字节[],然后手动写入数据,而不是编写身份验证数据的类。

我认为 java.net.Authenticator 或 System.setProperty 方法没有任何用处,因为我的实现需要在每个连接的基础上工作并且是线程安全的。

非常感谢任何帮助。

【问题讨论】:

    标签: java http authentication proxy socks


    【解决方案1】:

    取自 JSocks 项目来源: https://code.google.com/p/jsocks-mirror/source/browse/trunk/src/java/net/sourceforge/jsocks/socks/UserPasswordAuthentication.java

    我认为它足够干净,可以理解整个过程:

     /**
      SOCKS5 User Password authentication scheme.
    */
    public class UserPasswordAuthentication implements Authentication{
    
       /**SOCKS ID for User/Password authentication method*/
       public final static int METHOD_ID = 2;
    
       String userName, password;
       byte[] request;
    
       /**
         Create an instance of UserPasswordAuthentication.
         @param userName User Name to send to SOCKS server.
         @param password Password to send to SOCKS server.
       */
       public UserPasswordAuthentication(String userName,String password){
         this.userName = userName;
         this.password = password;
         formRequest();
       }
       /** Get the user name.
       @return User name.
       */
       public String getUser(){
         return userName;
       }
       /** Get password
       @return Password
       */
       public String getPassword(){
         return password;
       }
       /**
        Does User/Password authentication as defined in rfc1929.
        @return An array containnig in, out streams, or null if authentication
        fails.
       */
       public Object[] doSocksAuthentication(int methodId,
                                             java.net.Socket proxySocket)
                       throws java.io.IOException{
    
          if(methodId != METHOD_ID) return null;
    
          java.io.InputStream in = proxySocket.getInputStream();
          java.io.OutputStream out = proxySocket.getOutputStream();
    
          out.write(request);
          int version = in.read();
          if(version < 0) return null; //Server closed connection
          int status = in.read();
          if(status != 0) return null; //Server closed connection, or auth failed.
    
          return new Object[] {in,out};
       }
    
    //Private methods
    //////////////////
    
    /** Convert UserName password in to binary form, ready to be send to server*/
       private void formRequest(){
          byte[] user_bytes = userName.getBytes();
          byte[] password_bytes = password.getBytes();
    
          request = new byte[3+user_bytes.length+password_bytes.length];
          request[0] = (byte) 1; 
          request[1] = (byte) user_bytes.length;
          System.arraycopy(user_bytes,0,request,2,user_bytes.length);
          request[2+user_bytes.length] = (byte) password_bytes.length;
          System.arraycopy(password_bytes,0,
                           request,3+user_bytes.length,password_bytes.length);
       }
    }
    

    【讨论】:

    • 谢谢!我找不到任何关于 SOCKS 规范的信息来实现这样的东西。
    猜你喜欢
    • 2023-03-25
    • 2021-10-07
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 2020-12-07
    • 2013-07-31
    相关资源
    最近更新 更多