Как получить доступ к ClientCredentials из пользовательского IChannel или IChannelFactory?


Я создаю пользовательский канал в WCF для реализации пользовательского протокола безопасности. Нет, не убегай! Это не так страшно!

Проверка протокола на обслуживание является относительно простым. Самое сложное-это добавление сведений о безопасности в запрос на основе учетных данных клиента.

То, что я хочу сделать, - это получить доступ к объекту ClientCredentials (который прикреплен к используемому объекту ClientProxy) из моей реализации канала. Обычно я получаю доступ к этому через интернет. Behaviors свойство экземпляра ServiceEndpoint для конечной точки, которую я пытаюсь достичь:

var credentials = channel.Endpoint.Behaviors.Find<ClientCredentials>();
Однако я не могу найти способ получить доступ к конечной точке сервиса, с которой связан канал, из самого канала - почти нулевые метаданные доступны из класса ChannelBase. Есть ли способ получить конечную точку, с которой связан мой канал? Существует ли какой-либо альтернативный способ доступа к учетным данным клиента на стороне клиента?
2 4

2 ответа:

Стандартные каналы безопасности не используют ClientCredentials внутри системы. Вместо этого они говорят с SecurityTokenManager, который построен из ClientCredentials. Я рекомендую использовать некоторый дизассемблер для просмотра всей реализации.

В общем случае Ваш BindingElement должен построить и ChannelLister, и ChannelFactory и передать им всю необходимую информацию.

Реализуйте собственную клиентскую службу.

Например;

    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       
}

Теперь назовите его...

//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...