1

我有一个连接到一组 WCF Web 服务的 WPF 客户端。我们有一个 Dev、Test、Volume 和 Production 域,每个域的服务器上都有可用的服务。域没有信任关系。

目标是让客户端连接任何其他域的服务。如果客户端和服务器在同一个域中,则应发送默认网络凭据以进行身份​​验证/授权。如果服务器位于不同的域中,那么它应该向用户询问凭据,这与 Internet Explorer 在访问具有集成安全集的不同域中的站点时所做的方式非常相似。

目前,我正在尝试通过在为我的服务创建 ClientBase 实例时设置 DisplayInitializationUI() 来获取客户端凭据。

Client client = new Client(); // <- the wcf ClientBase implementation for the serivce.
client.Endpoint.Behaviors.Remove<ClientCredentials>();
client.Endpoint.Behaviors.Add<ClientCredentialsEx>();
client.DisplayInitializationUI();
client.InnerChannel.Open();

ClientCredentialsEx 类。

public class ClientCredentialsEx : ClientCredentials
{
    public ClientCredentialsEx() : base() { }
    public ClientCredentialsEx(ClientCredentialsEx other) : base(other) { }

    public override void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
    {
        behavior.InteractiveChannelInitializers.Add(new ShowCredentialUI());
        base.ApplyClientBehavior(serviceEndpoint, behavior);
    }
    protected override ClientCredentials CloneCore()
    {
        return new ClientCredentialsEx(this);
    }
}   

ShowCredentialUI 类实现 IInteractiveChannelInitializer。类的业务端是BeginDisplayInitializationUI方法;

public IAsyncResult BeginDisplayInitializationUI(IClientChannel channel, AsyncCallback callback, object state)
{
    string host = "";
    CREDUI_INFO info = new CREDUI_INFO();
    string username = string.Empty, password = string.Empty;

    CREDUI_FLAGS flags = CREDUI_FLAGS.GENERIC_CREDENTIALS |
                         CREDUI_FLAGS.SHOW_SAVE_CHECK_BOX |
                         CREDUI_FLAGS.EXPECT_CONFIRMATION;

    bool savePwd = false;

    // PromptForCredentials calls interop credui to challenge the user for username/password/smartcard.
    CredUIReturnCodes result = PromptForCredentials(ref info, host, 0, ref username,
                                                      ref password, ref savePwd, flags);


    ChannelParameterCollection collection = channel.GetProperty<ChannelParameterCollection>();
    collection.Add(new NetworkCredential(username, password));
    return new AsyncResult();
}

问题是当我调查 iis 日志时,从未发送过凭据。我怀疑我遗漏了一些重要的东西。有没有人成功实施过类似的场景?有没有更简单的方法来实现这一点?

谢谢阅读!

4

0 回答 0