我正在尝试在我的Java应用程序中支持经过身份验证的代理。我的理解是java.net.Proxy类不支持身份验证,您需要自己处理身份验证。
我已经创建了java.net.Proxy类的子类,它接受了两个额外的参数,用户名和密码。
实现HTTP代理身份验证非常简单,方法getHttpProxyAuthenticationHeader只返回base64编码的身份验证信息,传递给HttpUrlConnection或类似的。
我遇到了Sock代理问题。我找不到有关向Socks服务器发送身份验证的任何文档。我不确定是否需要使用诸如authenticateSocksProxy(OutputStream流)之类的方法在我的类中实现SOCKS身份验证协议,然后调用
authedProxy.authenticateSocksProxy(outputstream);
之前使用套接字
outputstream.writeBytes(myData.getBytes());
另一种选择是返回认证数据的byte [],然后手动写入数据,而不是写入认证数据的类。
我认为java.net.Authenticator或System.setProperty方法没有任何用处,因为我的实现需要在每个连接的基础上工作并且是线程安全的。
非常感谢任何帮助。
答案 0 :(得分:2)
我认为它足够清晰,可以理解完整的过程:
/**
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);
}
}