我有一个连接到一组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日志时,永远不会发送凭据。我怀疑我错过了一些至关重要的东西。有没有人有类似的方案成功实施?有没有更简单的方法来实现这一目标?
感谢阅读!