我有一个连接到一组 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 日志时,从未发送过凭据。我怀疑我遗漏了一些重要的东西。有没有人成功实施过类似的场景?有没有更简单的方法来实现这一点?
谢谢阅读!