使用用户名通过公司代理连接
Connect over company proxy with user name
我正在尝试连接到外部 IP 地址,但我在公司防火墙后面,所以我需要通过代理连接。
我运行一个curl测试:
curl -v https://IP_ADDRESS_OF_EXTERNAL_CLIENT:6125 -x http://MyComparyProxyAddress.com:8080 -U MYUSERNAME:MYPASSWORD
但我无法在 C# 中复制上述 cUrl 命令:
private static Socket CreateTunnelThruProxy(string destIP, int destPort)
{
string destUriWithPort = $"{destIP}:{destPort}";
UriBuilder uriBuilder = new UriBuilder(destUriWithPort);
Uri destUri = uriBuilder.Uri;
var proxy = new WebProxy("http://MyComparyProxyAddress.com", 8080);
proxy.UseDefaultCredentials = false;
proxy.Credentials = new NetworkCredential("MYUSERNAME", "MYPASSWORD");
WebRequest.DefaultWebProxy = proxy;
IWebProxy webProxy = WebRequest.DefaultWebProxy;
try
{
if (webProxy.IsBypassed(destUri))
return null;
}
catch (PlatformNotSupportedException)
{
// .NET Core doesn't support IWebProxy.IsBypassed
// (because .NET Core doesn't have access to Windows-specific services, of course)
return null;
}
Uri proxyUri = webProxy.GetProxy(destUri);
if (proxyUri == null)
return null;
IPAddress[] proxyEntry = Dns.GetHostAddresses(proxyUri.Host);
int iPort = proxyUri.Port;
IPAddress address = proxyEntry.First(a => a.AddressFamily == AddressFamily.InterNetwork);
IPEndPoint proxyEndPoint = new IPEndPoint(address, iPort);
Socket socketThruProxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketThruProxy.Connect(proxyEndPoint);
string proxyMsg = $"CONNECT {destIP}:{destPort} HTTP/1.1 \n\n";
byte[] buffer = Encoding.ASCII.GetBytes(proxyMsg);
byte[] buffer12 = new byte[50000];
socketThruProxy.Send(buffer, buffer.Length, 0);
int msg = socketThruProxy.Receive(buffer12, 50000, 0);
string data;
data = Encoding.ASCII.GetString(buffer12);
int index = data.IndexOf("200");
if (index < 0)
throw new ApplicationException(
$"Connection failed to {destUriWithPort} through proxy server {proxyUri.ToString()}.");
return socketThruProxy;
}
我不断从我的公司代理处获得以下信息:
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: NEGOTIATE
Proxy-Authenticate: NTLM
Proxy-Authenticate: BASIC realm="ztb"
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Proxy-Connection: close
Connection: close
Content-Length: 797
<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD>
<BODY>
<body bgcolor="#FFFFEA">
<blockquote>
<TABLE border=0 cellPadding=1 width="80%">
<TR><TD>
<FONT face="Verdana">
<big>Access Denied (authentication_failed)</big>
<BR>
<BR>
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Verdana">
Your credentials could not be authenticated: "Credentials are missing.". You will not be permitted access until your credentials can be verified.
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Verdana">
This is typically caused by an incorrect username and/or password, but could also be caused by network problems.
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Verdana" SIZE=2>
<BR>
For assistance, contact your Tech Desk . PXFFM25
</FONT>
</TD></TR>
</TABLE>
</blockquote>
</FONT>
</BODY></HTML>
我可以清楚地看到 webProxy 对象包含我设置的凭据,与 cUrl 一起使用的凭据相同。
我在尝试简单地调用时也遇到了同样的错误:
IWebProxy webProxy = WebRequest.GetSystemWebProxy();
而不是按照上面的代码片段手动设置凭据。所以看起来我的凭据没有被考虑....
有什么想法吗?
我之前尝试过这种情况,它通过创建继承 IWebProxy
的自定义代理 class 与我一起工作
public class MyProxy : IWebProxy
{
public ICredentials Credentials
{
get { return new NetworkCredential("your username","your password"); }
set { }
}
public Uri GetProxy(Uri destination)
{
return new Uri("http://MyComparyProxyAddress.com:8080");
}
public bool IsBypassed(Uri host)
{
return false;
}
}
并在应用程序配置文件中的配置节点中添加此部分
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="false">
<module type="yournamespace.MyProxy, your assembly name" />
</defaultProxy>
</system.net>
如果允许的话,我会把它添加为评论,但是添加域有帮助吗?过去,当我进行身份验证时,我必须确保域是正确的。每 Network Credential docs
有一个采用域的构造函数,或者您可以将其设置为 属性。
请勿尝试在您的代码中解决此问题。
使用 https://github.com/genotrance/px 等本地代理向企业代理提供您的用户凭据。
否则有一天您会在您的源代码管理中找到一个开发者密码。
我的一个项目遇到过这个问题,公司使用了防火墙(确切地说 Barracuda's firewall
)。我试过设置 WebProxy
并且还设置了机器代理,但没有成功。
我是这样解决的:
我已经要求安全团队将 IP 以及将用于该服务的端口列入白名单。所以任何传出或传入的连接都不会被阻止。然后,在应用程序中,我在 web.config
中设置代理,如下所示:
<system.net>
<defaultProxy>
<proxy usesystemdefault="False" proxyaddress="http://proxy_ip" bypassonlocal="False" />
</defaultProxy>
</system.net>
此外,在应用 运行 所在的服务器上设置了相同的代理。
这使事情按预期进行。
一周左右后,服务突然停止。当我检查与 Fiddler
的连接时,它告诉我 API 被重定向到另一台服务器(不同的 IP),防火墙阻止了它。所以,我让安全团队也把它列入白名单,服务又恢复了。
这可以通过以下方式完成:
if (IsProxyProvided(settings))
{
IPAddress[] proxyEntry = Dns.GetHostAddresses(settings.ProxyHost);
IPAddress address = proxyEntry.First(a => a.AddressFamily == AddressFamily.InterNetwork);
IPEndPoint proxyEndPoint = new IPEndPoint(address, settings.ProxyPort);
socket.Connect(proxyEndPoint);
if (AreProxyCredntialsProvided(settings))
{
var basicAuthBase64 = Convert.ToBase64String(
Encoding.GetEncoding("ISO-8859-1").GetBytes($"{settings.ProxyUserName}:{settings.ProxyUserNamePassword}"));
var proxyMessage = $"Proxy-Authorization: {string.Format("Basic {0}", basicAuthBase64)} \r\n";
var keepAlive = "Connection: keep-alive\r\n";
var request = $"CONNECT {endpoint.Address}:{endpoint.Port} HTTP/1.1 \r\n" + proxyMessage + keepAlive + "\r\n";
byte[] buffer = Encoding.ASCII.GetBytes(request);
socket.Send(buffer, buffer.Length, 0);
}
}
感谢维克多 Victor Stone who had similar issue here
我正在尝试连接到外部 IP 地址,但我在公司防火墙后面,所以我需要通过代理连接。
我运行一个curl测试:
curl -v https://IP_ADDRESS_OF_EXTERNAL_CLIENT:6125 -x http://MyComparyProxyAddress.com:8080 -U MYUSERNAME:MYPASSWORD
但我无法在 C# 中复制上述 cUrl 命令:
private static Socket CreateTunnelThruProxy(string destIP, int destPort)
{
string destUriWithPort = $"{destIP}:{destPort}";
UriBuilder uriBuilder = new UriBuilder(destUriWithPort);
Uri destUri = uriBuilder.Uri;
var proxy = new WebProxy("http://MyComparyProxyAddress.com", 8080);
proxy.UseDefaultCredentials = false;
proxy.Credentials = new NetworkCredential("MYUSERNAME", "MYPASSWORD");
WebRequest.DefaultWebProxy = proxy;
IWebProxy webProxy = WebRequest.DefaultWebProxy;
try
{
if (webProxy.IsBypassed(destUri))
return null;
}
catch (PlatformNotSupportedException)
{
// .NET Core doesn't support IWebProxy.IsBypassed
// (because .NET Core doesn't have access to Windows-specific services, of course)
return null;
}
Uri proxyUri = webProxy.GetProxy(destUri);
if (proxyUri == null)
return null;
IPAddress[] proxyEntry = Dns.GetHostAddresses(proxyUri.Host);
int iPort = proxyUri.Port;
IPAddress address = proxyEntry.First(a => a.AddressFamily == AddressFamily.InterNetwork);
IPEndPoint proxyEndPoint = new IPEndPoint(address, iPort);
Socket socketThruProxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketThruProxy.Connect(proxyEndPoint);
string proxyMsg = $"CONNECT {destIP}:{destPort} HTTP/1.1 \n\n";
byte[] buffer = Encoding.ASCII.GetBytes(proxyMsg);
byte[] buffer12 = new byte[50000];
socketThruProxy.Send(buffer, buffer.Length, 0);
int msg = socketThruProxy.Receive(buffer12, 50000, 0);
string data;
data = Encoding.ASCII.GetString(buffer12);
int index = data.IndexOf("200");
if (index < 0)
throw new ApplicationException(
$"Connection failed to {destUriWithPort} through proxy server {proxyUri.ToString()}.");
return socketThruProxy;
}
我不断从我的公司代理处获得以下信息:
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: NEGOTIATE
Proxy-Authenticate: NTLM
Proxy-Authenticate: BASIC realm="ztb"
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Proxy-Connection: close
Connection: close
Content-Length: 797
<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD>
<BODY>
<body bgcolor="#FFFFEA">
<blockquote>
<TABLE border=0 cellPadding=1 width="80%">
<TR><TD>
<FONT face="Verdana">
<big>Access Denied (authentication_failed)</big>
<BR>
<BR>
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Verdana">
Your credentials could not be authenticated: "Credentials are missing.". You will not be permitted access until your credentials can be verified.
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Verdana">
This is typically caused by an incorrect username and/or password, but could also be caused by network problems.
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Verdana" SIZE=2>
<BR>
For assistance, contact your Tech Desk . PXFFM25
</FONT>
</TD></TR>
</TABLE>
</blockquote>
</FONT>
</BODY></HTML>
我可以清楚地看到 webProxy 对象包含我设置的凭据,与 cUrl 一起使用的凭据相同。
我在尝试简单地调用时也遇到了同样的错误:
IWebProxy webProxy = WebRequest.GetSystemWebProxy();
而不是按照上面的代码片段手动设置凭据。所以看起来我的凭据没有被考虑....
有什么想法吗?
我之前尝试过这种情况,它通过创建继承 IWebProxy
的自定义代理 class 与我一起工作public class MyProxy : IWebProxy
{
public ICredentials Credentials
{
get { return new NetworkCredential("your username","your password"); }
set { }
}
public Uri GetProxy(Uri destination)
{
return new Uri("http://MyComparyProxyAddress.com:8080");
}
public bool IsBypassed(Uri host)
{
return false;
}
}
并在应用程序配置文件中的配置节点中添加此部分
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="false">
<module type="yournamespace.MyProxy, your assembly name" />
</defaultProxy>
</system.net>
如果允许的话,我会把它添加为评论,但是添加域有帮助吗?过去,当我进行身份验证时,我必须确保域是正确的。每 Network Credential docs
有一个采用域的构造函数,或者您可以将其设置为 属性。
请勿尝试在您的代码中解决此问题。 使用 https://github.com/genotrance/px 等本地代理向企业代理提供您的用户凭据。 否则有一天您会在您的源代码管理中找到一个开发者密码。
我的一个项目遇到过这个问题,公司使用了防火墙(确切地说 Barracuda's firewall
)。我试过设置 WebProxy
并且还设置了机器代理,但没有成功。
我是这样解决的:
我已经要求安全团队将 IP 以及将用于该服务的端口列入白名单。所以任何传出或传入的连接都不会被阻止。然后,在应用程序中,我在 web.config
中设置代理,如下所示:
<system.net>
<defaultProxy>
<proxy usesystemdefault="False" proxyaddress="http://proxy_ip" bypassonlocal="False" />
</defaultProxy>
</system.net>
此外,在应用 运行 所在的服务器上设置了相同的代理。
这使事情按预期进行。
一周左右后,服务突然停止。当我检查与 Fiddler
的连接时,它告诉我 API 被重定向到另一台服务器(不同的 IP),防火墙阻止了它。所以,我让安全团队也把它列入白名单,服务又恢复了。
这可以通过以下方式完成:
if (IsProxyProvided(settings))
{
IPAddress[] proxyEntry = Dns.GetHostAddresses(settings.ProxyHost);
IPAddress address = proxyEntry.First(a => a.AddressFamily == AddressFamily.InterNetwork);
IPEndPoint proxyEndPoint = new IPEndPoint(address, settings.ProxyPort);
socket.Connect(proxyEndPoint);
if (AreProxyCredntialsProvided(settings))
{
var basicAuthBase64 = Convert.ToBase64String(
Encoding.GetEncoding("ISO-8859-1").GetBytes($"{settings.ProxyUserName}:{settings.ProxyUserNamePassword}"));
var proxyMessage = $"Proxy-Authorization: {string.Format("Basic {0}", basicAuthBase64)} \r\n";
var keepAlive = "Connection: keep-alive\r\n";
var request = $"CONNECT {endpoint.Address}:{endpoint.Port} HTTP/1.1 \r\n" + proxyMessage + keepAlive + "\r\n";
byte[] buffer = Encoding.ASCII.GetBytes(request);
socket.Send(buffer, buffer.Length, 0);
}
}
感谢维克多 Victor Stone who had similar issue here