如何在WCF中正确使用DisplayInitializationUI以提示用户凭据在不同域中进行身份验证和使用Web服务?

时间:2009-11-05 22:16:17

标签: wcf-security wcf-client

我有一个连接到一组WCF Web服务的WPF客户端。我们有一个开发,测试,批量和生产域,每个域中的服务器上都有可用的服务。域名没有信任关系。

目标是让客户端连接任何其他域的服务。如果客户端和服务器位于同一域中,则应发送默认网络凭据以进行身份​​验证/授权。如果服务器位于不同的域中,那么它应该向用户挑战凭据,就像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日志时,永远不会发送凭据。我怀疑我错过了一些至关重要的东西。有没有人有类似的方案成功实施?有没有更简单的方法来实现这一目标?

感谢阅读!

0 个答案:

没有答案