如何在WCF中应用基本身份验证?

时间:2020-02-14 01:05:36

标签: c# .net wcf wcf-security

我正在实现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的成员,但只能获取。这就是为什么我认为这必须是一种在调用CreateChannel之前设置凭据的方法

谢谢

1 个答案:

答案 0 :(得分:1)

这里的描述可能有问题,您的想法是正确的,在这里我们可以设置客户端身份验证凭据。

<Style TargetType="{x:Type TextBox}" BasedOn="{x:Null}">
   <Style.Triggers>
      <DataTrigger Binding="{Binding SelectedItem.IsNotCorrect, RelativeSource={RelativeSource AncestorType=ComboBox}}" Value="True">
          <Setter Property="Foreground" Value="Red" />
          <Setter Property="FontWeight" Value="Bold" />
      </DataTrigger>
   </Style.Triggers>
</Style>

此外,请注意,通道工厂使用的绑定类型应与服务器端的绑定类型一致。
随时让我知道问题是否仍然存在。

相关问题