Как применить аутентификацию basi c в WCF? - PullRequest
0 голосов
/ 14 февраля 2020

Я реализую WcfClientFactory

public class WcfClientFactory : IDisposable
{
    internal const string WildcardConfigurationName = "*";

    //We track all channels created by this instance so they can be destroyed
    private readonly List<WeakReference<IDisposable>> _disposableItems = new List<WeakReference<IDisposable>>();

    public T CreateClient<T>(string configurationName = WildcardConfigurationName, string address=null)
    {
        var factory = new ChannelFactory<T>(configurationName);
        if (!string.IsNullOrWhiteSpace(address))
        {
            factory.Endpoint.Address = new EndpointAddress(address);
        }
        var channel = factory.CreateChannel();
        var clientChannel = (IClientChannel)channel;

        clientChannel.Open();
        _disposableItems.Add(new WeakReference<IDisposable>(clientChannel,false));
        return channel;
    }

    void IDisposable.Dispose()
    {
        //No finalizer is implemented as there are no directly held scarce resources. 
        //Presumably the finalizers of items in disposableItems will handle their own teardown 
        //if it comes down to it.
        foreach (var reference in _disposableItems)
        {
            IDisposable disposable;
            if (reference.TryGetTarget(out disposable))
            {
                disposable.Dispose();
            }
        }
    }
}

Так что я могу создать WCF clientChannel

var client = _wcfClientFactory.CreateClient<ICrmService>(address);

Он работает нормально, если WCF не имеет никакой аутентификации. Теперь мы хотим добавить аутентификацию на эту фабрику. Как мне это сделать? Я попробовал ниже код

public T CreateClientWithBasicAuthentication<T>(string address)
{
    WSHttpBinding myBinding = new WSHttpBinding();
    myBinding.Security.Mode = SecurityMode.Transport;
    myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

    var factory = new ChannelFactory<T>(myBinding, new EndpointAddress(address));
    var channel = factory.CreateChannel();
    var clientChannel = (IClientChannel)channel;

    ////CrmServiceClient csc = (CrmServiceClient)channel;
    ////csc.ClientCredentials.UserName.UserName = _UserName;
    ////csc.ClientCredentials.UserName.Password = _Password;

    clientChannel.Open();
    _disposableItems.Add(new WeakReference<IDisposable>(clientChannel, false));

    return channel;
}

Но он генерирует исключение и запрашивает имя пользователя и пароль. Как я могу установить пароль и имя пользователя?

У фабрики переменных есть член Credential, но он только get. Вот почему я думаю, что это должен быть способ установить учетные данные перед вызовом CreateChannel

Спасибо

1 Ответ

1 голос
/ 14 февраля 2020

Здесь может быть проблема с описанием, ваша идея верна, здесь мы можем установить учетные данные для аутентификации клиента.

var factory = new ChannelFactory<T>(myBinding, new EndpointAddress(address));
            //for HttpClientCredentialType.Basic
            factory.Credentials.UserName.UserName = "administrator";
            factory.Credentials.UserName.Password = "abcd1234!";
            //for window credentials
            //factory.Credentials.Windows.ClientCredential.UserName = "adminsitrator";
            //factory.Credentials.Windows.ClientCredential.Password = "abcd1234!";
            var channel = factory.CreateChannel();

Кроме того, обратите внимание, что тип привязки, который использует фабрика каналов, должен быть согласованным с типом привязки на стороне сервера.
Не стесняйтесь сообщить мне, если проблема все еще существует.

...