.NET Framework Developer Center > .NET Framework Forums > Windows Communication Foundation (WCF) > Authenticating to Proxy and Service destination with username password.

Answered Authenticating to Proxy and Service destination with username password.

  • Tuesday, January 16, 2007 11:01 AM
     
     

    Hi,

    kennyw blogged about this a while ago http://kennyw.com/indigo/143 and i seem to be running into this problem.

    As 'proxy authentication' and 'service authentication' use the same credentials store i cannot log on to the service with username/password credentials and log on to the proxy with different username/password credentials. I am running into this problem by several clients who try to access our service.

    The current implementation of this in  WCF is very limitting to me, how should i go about to fixing this problem?

    Jusy for your information its not acceptable to use the same username password combination at the service and proxy (as this involves 2 different companies.)

Answers

  • Friday, January 19, 2007 12:29 PM
     
     Answered

    Hi Sajay,

    The client is organisation A and connects to the internet through a (username/password) Authenticated Proxy, the Service is managed by organisation B and requires username/password authentication. WCF only has 1 credential store that is used to authenticate to both the proxy and the service, this leads to a problem is both the proxy and service require the same credential type because you can only provide 1 set of each type (other types include Windows or Certificate, ...).

    I hope this made the situation a bit more understandable.. (also see the link in my first post.)

    But now for some good news we found a solution to this problem with a little help from MS and its actually quite simple...

    Instead of setting the proxy adress and authentication type on the binding like the example below.

    WSHttpBinding binding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential, true);
    binding.ProxyAdress = new Uri(http://proxy.com:8080);
    binding.Security.Transport.ProxyCredentialType
    = HttpProxyCredentialType.Basic;

    ChannelFactory<IService> communication = new ChannelFactory<IService>(binding, endpoint);
    //Conflict can only set 1 set of Username/Password credential (is used for both the proxy and the service but they are not the same)
    communication.Credentials.UserName.UserName = "user";
    communication.Credentials.UserName.Password = "pass";

    Solution: We now changed to use the DefaultWebProxy on the binding and set a new web proxy object to the WebRequest context with the address and credentials for the proxy. And now the credentials on the channelfactory can be used for the Service credentials see below.

    binding.UseDefaultWebProxy = true;

    WebProxy proxyObject = new WebProxy("ProxyAddress");
    proxyObject.Credentials = new NetworkCredential("ProxyUser", "ProxyPassword");
    WebRequest.DefaultWebProxy = proxyObject;

     

    Hope this helps someone else.

     

All Replies

  • Wednesday, January 17, 2007 4:04 PM
     
     
    Or cant this be fixed?
  • Friday, January 19, 2007 8:01 AM
    Moderator
     
     
    Could you elaborate on your last statement on the proxy and the service being 2 different organizations?
  • Friday, January 19, 2007 12:29 PM
     
     Answered

    Hi Sajay,

    The client is organisation A and connects to the internet through a (username/password) Authenticated Proxy, the Service is managed by organisation B and requires username/password authentication. WCF only has 1 credential store that is used to authenticate to both the proxy and the service, this leads to a problem is both the proxy and service require the same credential type because you can only provide 1 set of each type (other types include Windows or Certificate, ...).

    I hope this made the situation a bit more understandable.. (also see the link in my first post.)

    But now for some good news we found a solution to this problem with a little help from MS and its actually quite simple...

    Instead of setting the proxy adress and authentication type on the binding like the example below.

    WSHttpBinding binding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential, true);
    binding.ProxyAdress = new Uri(http://proxy.com:8080);
    binding.Security.Transport.ProxyCredentialType
    = HttpProxyCredentialType.Basic;

    ChannelFactory<IService> communication = new ChannelFactory<IService>(binding, endpoint);
    //Conflict can only set 1 set of Username/Password credential (is used for both the proxy and the service but they are not the same)
    communication.Credentials.UserName.UserName = "user";
    communication.Credentials.UserName.Password = "pass";

    Solution: We now changed to use the DefaultWebProxy on the binding and set a new web proxy object to the WebRequest context with the address and credentials for the proxy. And now the credentials on the channelfactory can be used for the Service credentials see below.

    binding.UseDefaultWebProxy = true;

    WebProxy proxyObject = new WebProxy("ProxyAddress");
    proxyObject.Credentials = new NetworkCredential("ProxyUser", "ProxyPassword");
    WebRequest.DefaultWebProxy = proxyObject;

     

    Hope this helps someone else.

     

  • Wednesday, October 10, 2007 1:06 AM
     
     

     

    @#$##% hell, it took me nearly a day an a half of googling to find this post!!! Thank you!!!  It seems obvious when you think about it... but how the hell are we to know that WCF's pumbing uses the object returned by WebRequest.DefaultWebProxy !!!!!
  • Wednesday, October 10, 2007 4:31 AM
     
     

    I couldn't even get my requests to authenticate against our company proxy when using the original code path...

     

    Code Block

    static readonly string sProxyURL = "http://abc.def.ghi.com:8080";

    static readonly string sEndPointURL = "http://xml.searchvideo.com/apiv3";

    static readonly string sUsername = "username";

    static readonly string sPassword = "password";

    static readonly string sDomain = "domain";

     

    // create a binding object as per usual, with an end point to the webservice you want to use

    WebHttpBinding objWCFBinding = new WebHttpBinding();

    EndpointAddress objEndpoint = new EndpointAddress(sEndPointURL);

     

    // configure binding to use custom proxy configuration

    objWCFBinding.UseDefaultWebProxy = false;  

    objWCFBinding.ProxyAddress = new Uri(sProxyURL);

                

    // configure proxy credentials type

    objWCFBinding.Security.Transport.ProxyCredentialType = WebHttpProxyCredentialType.Basic;

     

    // not sure if this is required...

    objWCFBinding.Security.Transport.Realm = "abc.def.ghi.com";

     

    // create the required channel factory using the requirec interface

    ChannelFactory<IAolVideoSearchService> objChannelFactory = new ChannelFactory<IAolVideoSearchService>(objWCFBinding, objEndpoint);

     

    // in this case the AOL webservice is a "web http" service, so we add the default

    // behavior object as well

    WebHttpBehavior objWebBehavior = new WebHttpBehavior();

    objChannelFactory.Endpoint.Behaviors.Add(objWebBehavior);

                   

    // configure the credentials that are to be supplied when we get the

    // challenge from the proxy server

    objChannelFactory.Credentials.UserName.UserName = string.Format("{0}\\{1}", sDomain, sUsername);

    objChannelFactory.Credentials.UserName.Password = sPassword;

     

    // everything is now configured, create the channel

    IAolVideoSearchService objAolVideoSearchService = objChannelFactory.CreateChannel();

     

    // executing the Search method exposed by IAolVideoSearchService interface

    // results in an exception being thrown with the message

    // "The remote server returned an unexpected response: (407) Proxy Authentication Required."

    objResponse = objAolVideoSearchService.Search("1x1jhj64466mi12ia", "truveo.videos.getVideos", "Unicef");

     

     

     

     

    Using the alternative code path (as suggested) works!!! Any suggestions most appreciated...

     

    Code Block

    static readonly string sProxyURL = "http://abc.def.ghi.com:8080";

    static readonly string sEndPointURL = "http://xml.searchvideo.com/apiv3";

    static readonly string sUsername = "username";

    static readonly string sPassword = "password";

    static readonly string sDomain = "domain";

     

    // create web proxy object and set it to the DEFAULT web proxy via the WebRequest.DefaultWebProxy static property

    WebRequest.DefaultWebProxy = new WebProxy(sProxyURL);

     

    // update the credentials of the default web proxy object

    WebRequest.DefaultWebProxy.Credentials = new NetworkCredential(sUsername, sPassword, sDomain);

                   

    // create a binding object as per usual, with an end point to the webservice you want to use

    WebHttpBinding objWCFBinding = new WebHttpBinding();

    EndpointAddress objEndpoint = new EndpointAddress(sEndPointURL);

     

    // DO NOT set the ProxyAddress and UseDefaultWebProxy properties

    // of the binding object!!!  leave them alone!  If they have

    // been changed then they need to be set as such

    //

    //objWCFBinding.ProxyAddress = null;

    //objWCFBinding.UseDefaultWebProxy = true;

     

    // create the required channel factory using the required interface

    ChannelFactory<IAolVideoSearchService> objChannelFactory = new ChannelFactory<IAolVideoSearchService>(objWCFBinding, objEndpoint);

     

    // in this case the AOL webservice is a "web http" service, so we add the default

    // behavior object as well

    WebHttpBehavior objWebBehavior = new WebHttpBehavior();

    objChannelFactory.Endpoint.Behaviors.Add(objWebBehavior);

    // everything is now configured, create the channel

    IAolVideoSearchService objAolVideoSearchService = objChannelFactory.CreateChannel();

     

     

    Thanks!

  • Wednesday, November 11, 2009 12:33 PM
     
     
    Hi, Paul:

    Thanks for your alternative solution. And it also works for me. Great!

    Is this issue caused by Microsoft intentionaly or just be ignored? It took me 2 days to try to find solution.

    ____...