How I access ClientCredentials from with a custom IChannel or IChannelFactory?
I'm creating a custom channel in WCF in order to implement a custom security protocol. No, don't run away! It's not that scary!
Verifying the protocol on the service is relatively simple. The hard part is adding the security information to the request based on the client credentials.
What I want to do is acce开发者_StackOverflow中文版ss the ClientCredentials
object (the one attached to the ClientProxy
in use) from within my channel implementation. Normally, I'd get access to this through the Behaviors
property on the ServiceEndpoint
instance for the endpoint I'm trying to reach:
var credentials = channel.Endpoint.Behaviors.Find<ClientCredentials>();
However, I can't seem to find a way to access the service endpoint the channel is associated with from within the channel itself - almost zero metadata is available from the ChannelBase
class.
Is there a way to get the endpoint my channel is associated with? Is there any alternative way to access the client credentials on the client-side?
Standard security channels don't use ClientCredentials
internally. They instead talk with SecurityTokenManager
which is constructed from ClientCredentials
. I recommend using some disassembler to browse whole implementation.
Generally your BindingElement
should build both ChannelLister
and ChannelFactory
and pass them all information they need.
Implement you own client service.
For example;
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
public class UserClient : ClientBase<IAsyncESPUserService> , IESPUserService
{
/// <summary>
/// Constructor - No Parameters, this will use a default target endpoint.
/// </summary>
public UserClient() : base() { }
/// <summary>
/// Constructor - Binding and Address Parameters
/// </summary>
/// <param name="binding">How we are communicating.</param>
/// <param name="address">The address we are communicating to.</param>
public UserClient(Binding binding, EndpointAddress address) : base(binding, address) { }
/// <summary>
/// Constructor - Configuration Name Parameter
/// </summary>
/// <param name="endpointConfigurationName">The name of the configuration in ServiceReferences.ClientConfig. </param>
public UserClient(string endpointConfigurationName) : base(endpointConfigurationName) { }
//Implement your async service calls here
}
Now call it...
//Create using the default endpoint
UserClient client = new UserClient();
//Set user name and password with call
System.ServiceModel.Description.ClientCredentials loginCredentials = new System.ServiceModel.Description.ClientCredentials();
loginCredentials.UserName.UserName = "test";
loginCredentials.UserName.Password = "test";
//Attach Credentials, Can't do this in config file
var defaultCredentials = client.ChannelFactory.Endpoint.Behaviors.Find<System.ServiceModel.Description.ClientCredentials>();
client.ChannelFactory.Endpoint.Behaviors.Remove(defaultCredentials);
client.ChannelFactory.Endpoint.Behaviors.Add(loginCredentials);
//Now make a call to a service method...
精彩评论