我有一个C#app,它通过代理服务器调用WCF服务。 代理和WCF服务都需要(不同的)凭据。 我正在使用svcutil生成的代理类来访问WCF服务。
当我关闭代理服务器对凭据的要求时,我可以正常访问WCF服务,所以我想知道的是知道在哪里应用代理服务器的凭据(我在我的开发环境中使用Fiddler)。
我已经阅读过各种帖子,说明在client.ClientCredentials
设置凭据,这似乎适用于代理服务器凭据或WCF服务凭据,但我无法同时存储。
如果我将代理服务器凭据放在client.ClientCredentials
中,则请求会命中WCF服务,但会被拒绝。
如果我将WCF服务凭据放在client.ClientCredentials
中,则请求不会通过代理服务器。
有没有办法提供两组不同的凭据,以便我可以通过代理服务器和WCF服务进行身份验证?我需要在代码中执行此操作,而不是在配置文件中执行此操作。
代码如下:
public class Runner
{
public int GetAvailableFacilities(int timeoutInSeconds, string uri, string userName, string password)
{
FacilitySearchServiceClient client = null;
try
{
client = SetClient(timeoutInSeconds, uri, userName, password, client);
string outputMessage = null;
int[] availableFacilities = client.GetAvailableFacilities(out outputMessage);
return availableFacilities.Length;
}
finally
{
if (client != null)
{
client.Close();
}
}
}
private FacilitySearchServiceClient SetClient(int timeoutInSeconds, string uri, string wcfServiceUserName, string wcfServicePassword, FacilitySearchServiceClient client)
{
string proxyServerUsername = "1";//Fiddler
string proxyServerPassword = "1";//Fiddler
client = new FacilitySearchServiceClient(ConfigureServiceBinding(timeoutInSeconds), new EndpointAddress(uri));
//If this is the only uncommented call to SetServiceCredentials the proxy server transmits the request
//to the wcf service which then rejects the authentication attempt.
SetServiceCredentials(client.ClientCredentials, proxyServerUsername, proxyServerPassword);
//If this is the only uncommented call to SetServiceCredentials the proxy server rejects the authentication attempt,
//resulting in an EndpointNotFoundException.
SetServiceCredentials(client.ClientCredentials, wcfServiceUserName, wcfServicePassword);
return client;
}
protected static void SetServiceCredentials(ClientCredentials credentials, string userName, string password)
{
credentials.UserName.UserName = userName;
credentials.UserName.Password = password;
}
protected CustomBinding ConfigureServiceBinding(int timeoutInSeconds)
{
CustomBinding binding = new CustomBinding();
SecurityBindingElement sbe = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
sbe.IncludeTimestamp = false;
sbe.EnableUnsecuredResponse = true;
sbe.AllowInsecureTransport = true;
binding.Elements.Add(sbe);
binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, System.Text.Encoding.UTF8));
binding.Elements.Add(CreateHttpsBindingElement(Const.ProxyServerUrl));
return binding;
}
/// <summary>
/// Sets up the element needed for the web service call.
/// </summary>
private static HttpsTransportBindingElement CreateHttpsBindingElement(string proxyUri)
{
HttpsTransportBindingElement tpt = new HttpsTransportBindingElement();
tpt.TransferMode = TransferMode.Streamed;
tpt.MaxReceivedMessageSize = Int32.MaxValue;
tpt.MaxBufferSize = Int32.MaxValue;
tpt.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
if (string.IsNullOrEmpty(proxyUri) == false)
{
tpt.ProxyAddress = new Uri(proxyUri);
tpt.UseDefaultWebProxy = false;
tpt.ProxyAuthenticationScheme = System.Net.AuthenticationSchemes.Basic;
}
return tpt;
}
}
答案 0 :(得分:1)
HttpWebRequest
对象公开类型为System.Net.WebProxy
的代理属性。在这种情况下,您可以使用Credentials
类型的System.Net.WebProxy
属性来实现您要执行的操作。在您的情况下,您可以通过修改.NET应用程序的所有Web请求的代理凭据,修改Global.asax.cs中的Application_Start方法(假设您的客户端也是Web应用程序),为WCF客户端执行此操作。否则,您可以在客户端应用程序的相应启动方法中使用此代码。
protected void Application_Start(Object sender, EventArgs e)
{
var proxy = new WebProxy("myproxyservername", <myproxyPort>) { Credentials = new System.Net.NetworkCredential("yourproxyusername", "yourproxypassword") };
WebRequest.DefaultWebProxy = proxy;
}