Java 中的每代理身份验证
Per-Proxy Authentication in Java
我正在尝试在我的 Java 应用程序中支持经过身份验证的代理。我的理解是 java.net.Proxy class 不支持认证,你需要自己处理认证。
我创建了 java.net.Proxy class 的子class,它需要两个额外的参数,用户名和密码。
实施 HTTP 代理身份验证非常容易,方法 getHttpProxyAuthenticationHeader 只是 returns base64 编码的身份验证信息,传递给 HttpUrlConnection 或类似的。
不过我在使用 Sock 代理时遇到了问题。我找不到任何关于向 Socks 服务器发送身份验证的文档。我不确定是否需要在我的 class 中使用诸如 authenticateSocksProxy(OutputStream stream) 之类的方法实现 SOCKS 身份验证协议,然后调用
authedProxy.authenticateSocksProxy(outputstream);
在使用类似
的套接字之前
outputstream.writeBytes(myData.getBytes());
另一种选择是 return 验证数据的一个字节[],然后手动写入数据,而不是 class 写入验证数据。
我认为 java.net.Authenticator 或 System.setProperty 方法没有任何用处,因为我的实现需要在每个连接的基础上工作并且是线程安全的。
非常感谢任何帮助。
取自 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);
}
}
我正在尝试在我的 Java 应用程序中支持经过身份验证的代理。我的理解是 java.net.Proxy class 不支持认证,你需要自己处理认证。
我创建了 java.net.Proxy class 的子class,它需要两个额外的参数,用户名和密码。
实施 HTTP 代理身份验证非常容易,方法 getHttpProxyAuthenticationHeader 只是 returns base64 编码的身份验证信息,传递给 HttpUrlConnection 或类似的。
不过我在使用 Sock 代理时遇到了问题。我找不到任何关于向 Socks 服务器发送身份验证的文档。我不确定是否需要在我的 class 中使用诸如 authenticateSocksProxy(OutputStream stream) 之类的方法实现 SOCKS 身份验证协议,然后调用
authedProxy.authenticateSocksProxy(outputstream);
在使用类似
的套接字之前outputstream.writeBytes(myData.getBytes());
另一种选择是 return 验证数据的一个字节[],然后手动写入数据,而不是 class 写入验证数据。
我认为 java.net.Authenticator 或 System.setProperty 方法没有任何用处,因为我的实现需要在每个连接的基础上工作并且是线程安全的。
非常感谢任何帮助。
取自 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);
}
}