开发者

Using ChannelFactory<T> To Create Channels with Different Credentials

开发者 https://www.devze.com 2023-04-12 12:13 出处:网络
I am using the ChannelFactory<T> type to create channels into a WsHttpBinding WCF web service, and the service uses a username/password combination to authenticate. While I have the authenticati

I am using the ChannelFactory<T> type to create channels into a WsHttpBinding WCF web service, and the service uses a username/password combination to authenticate. While I have the authentication working using my custom validator, I am having difficulty creating channels with differing credentials.

Given the overhead of creating ChannelFactory<T>, I'm trying to cache a single instance of it and share it for the creation of multiple channels over the lifetime of my application. Unfortunately, it seems like the credentials are directly tied to the factory and cannot be changed after a channel has been created.

In other words, if I try this:

factory.Credentials.UserName.UserName = "Bob";
factory.Credentials.UserName.Password = "password";

var channel1 = factory.CreateChannel();

factory.Credentials.UserName.UserName = "开发者_Go百科Alice"; // exception here
factory.Credentials.UserName.Password = "password";

var channel1 = factory.CreateChannel();

I get an exception telling me that the UserName property is now read-only.

Is it possible to implement any sort of caching here, or am I essentially going to have to cache an instance of ChannelFactory for every username?


As documented on MSDN this is not directly possible (Credentials become readonly upon Open of the ChannelFactory)... if you really want to do this you will need to trick the ChannelFactory like this:

// step one - find and remove default endpoint behavior 
var defaultCredentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();
factory.Endpoint.Behaviors.Remove(defaultCredentials); 


// step two - instantiate your credentials
ClientCredentials loginCredentials = new ClientCredentials();
loginCredentials.UserName.UserName = "Username";
loginCredentials.UserName.Password = "Password123";


// step three - set that as new endpoint behavior on factory
factory.Endpoint.Behaviors.Add(loginCredentials); //add required ones

Another option seems to be to Close() the ChannelFactory before trying to change the Credentials .

Otherwise just stick with caching different ChannelFactories for different Credentials...


You'll need to create a new channel factory. When the factory creates the first channel, its properties become read-only (some throw the exception as you see; some others are worse in which you change but nothing happens, for example if you change some property in a binding element which you passed to the CF constructor).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号