抱歉标题太长了。
这是关于 WCF 配置和安全性的。我有以下情况:
- 一台服务器 (IIS)
- N 个客户端(WPF 应用程序)
- 用于在客户端和服务器之间进行通信的 Web 服务
- 一切都在同一个局域网和同一个域中
- 我需要一些双工通信,以便服务器可以通知所有客户端(无轮询,但使用 WCF 回调)
- 用户凭据(登录名/密码)由活动目录管理
- 用户身份验证是“每个用户”,而不是“每个 Windows 帐户”或“每个机器”
理想情况下,我希望有 2 种不同的服务:
一个需要 WCF 会话,以便我可以使用回调:
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IService1Callback))]
public interface IService1
{
[OperationContract(IsOneWay = false, IsInitiating = true)]
void Subscribe();
[OperationContract(IsOneWay = false, IsTerminating = true)]
void Unsubscribe();
}
一个没有,所以我可以使用旧的方式来编写无状态、高效和可维护的服务:每个 WCF 调用都经过身份验证、授权,并在服务器端生成一个新的 Service 实现实例:
[ServiceContract]
public interface IService2
{
[OperationContract]
int DoSomeStuff();
}
问题是,我们希望每个客户端都针对活动目录进行身份验证。因此,在客户端应用程序启动时,每个客户端都必须指定登录名、密码和域。问题是 AD 身份验证非常耗时:
using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "theDomain"))
{
if (!pc.ValidateCredentials("theUser", "thePassword"))
{
throw new SecurityException();
}
}
我的第一个想法是使用该IService1
服务(负责发送回调)作为身份验证服务:
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IService1Callback))]
public interface IService1
{
[OperationContract(IsOneWay = false, IsInitiating = true)]
void Login(string login, string password, string domain);
[OperationContract(IsOneWay = false, IsTerminating = true)]
void Logout();
}
所以在Login
操作实现中,我们可以只检查一次用户登录/密码对 AD 的检查,并依赖 WCF 会话来处理来自客户端的下一个 WCF 请求。问题是,我不想IService1
因为会话模式而对服务发出其他请求Required
,InstanceContextMode
也就是说PerSession
(是的,除了登录/注销/客户端通知之外,我想避免其他操作的丑陋的客户端代理单例模式) .
所以问题是:我如何构建和配置我的服务,所以:
- 我不需要针对每个 WCF 请求向 AD 提出请求
- 我有一些服务器回调
IService2
对于回调服务(不是“实际”服务),我每个会话只有单例模式/会话所需/实例上下文
我在想wsHttpBinding
forIService2
和netTcpBinding
for IService1
。关于传输安全性(传输或消息)的选择和凭证类型(Windows、用户名、..?)的选择,我不确定。
任何帮助将不胜感激。