3

我们正在开发 WCF 服务来容纳我们的核心 API。

我们正在开发 2 个客户端以使用此 API,其中一个是 WPF 桌面应用程序,它很可能会针对 Active Directory 进行身份验证并与 API 位于同一域中。另一个是 ASP.Net Web 应用程序,它很可能会使用 ASP.Net Membership 来确保安全,并且仍然与 WCF 服务位于同一个域中。该计划是让 WCF 服务使用 NetTcp 并托管在 Windows 服务中。

在可能的情况下,我希望 WCF 服务作为调用用户运行,我想这对于用户是域用户的桌面应用程序来说应该是相当直接的。对于网络应用程序,我想我需要创建一个用户来运行服务调用。

是否有可能让这种双重安全方法在单个 WCF 服务上运行,或者我需要使用自己的安全模型制作 2 个服务?

此外,如果有人对实现这一目标的最佳实践/模式有任何想法,那就太好了。

谢谢

4

2 回答 2

4

我通过以下方式解决了同样的问题:

  1. 我为每次使用创建了两个 net.tcp 绑定。

      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="" />
        <message clientCredentialType="UserName" />
      </security>
    
    </binding>
    <binding name="WindowsBinding" >
    
      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="Windows" />
      </security>
    
    </binding>
    

  2. 接下来,我为每个服务添加了两个端点

    <service name="SimplePluginService" behaviorConfiguration="CommonBehavior">
    
       <endpoint binding="netTcpBinding" bindingConfiguration="UserNameBinding" name="SimplePluginServiceUserName" contract="ISimplePluginService">
           <identity>
                <dns value="WCfServer" />
           </identity>
       </endpoint>
    
       <endpoint binding="netTcpBinding" bindingConfiguration="WindowsBinding" name="SimplePluginServiceWindows" contract="ISimplePluginService">
           <identity>
                <dns value="WCfServer" />
           </identity>
        </endpoint>
    
    </service>
    
  3. 接下来,我在创建 ChannelFactory 时选择了适当的端点(ConnectionManager - 类,其中包含有关用户信用的信息)。

    private readonly Dictionary<Type, Object> channelFactoryDictionary = new Dictionary<Type, Object>();
    
    private ChannelFactory<T> GetChannelFactory<T>() where T : class
    {
        if (channelFactoryDictionary.Keys.Contains(typeof(T)))
        {
            return channelFactoryDictionary[typeof(T)] as ChannelFactory<T>;
        }
        else
        {
            string endpointName=typeof(T).ToString();
            if (ConnectionManager.IsWindowsAuth) endpointName+="Windows";
            else  endpointName+="UserName";
    
            ChannelFactory<T> channelFactory = new ChannelFactory<T>(endpointName);
    
            if (!ConnectionManager.IsWindowsAuth){
                 channelFactory.Credentials.UserName.UserName = ConnectionManager.Password;
                 channelFactory.Credentials.UserName.Password = ConnectionManager.Password;
            }
    
            channelFactoryDictionary.Add(typeof(T), channelFactory);
            return channelFactory;
        }
    }
    
于 2012-07-20T06:39:01.340 回答
0

你在这里混淆了几个不同的问题。首先,我声称您的托管(Windows 服务)和传输(此处以 netTcp 给出)与您选择的身份验证/授权几乎无关,除非您想依赖 ASP.NET 成员资格,在这种情况下您需要IIS 来托管您的服务。

在桌面或精心策划的 LDAP 环境中,模拟无疑是一种不错的访问控制方法。不过,我倾向于发现,随着我的服务的增长,它们的业务需求会偏离 Active Directory 中表示(或可以表示)的策略。一旦发生这种情况,您的服务就开始需要更多支持来保持 Windows 模拟按您的意愿工作。这通常意味着处理 WCF 可扩展性。

从多年的经验来看,使用 WCF 安全扩展点与几乎没有麻醉的根管一样痛苦。也就是说,一旦完成了痛苦的工作,它就非常强大。

我发现,一般来说,疼痛越少越好。我可以通过在我的代码中显式地建模访问限制来获得模拟的安全优势,例如使用基于声明的安全性和 CAS 属性。采用这种方法,自定义IPrincipal实现类可以消除对模拟的需要,并且使用它可以消除非常模糊的 WCF 管道。

这不是您要寻找的答案,但这些仍然是我的两美分的价值。

于 2012-07-26T00:09:24.527 回答