WCF Windows 服务数据库连接和模拟问题

Posted

技术标签:

【中文标题】WCF Windows 服务数据库连接和模拟问题【英文标题】:WCF Windows service DB connexion and impersonation question 【发布时间】:2011-08-12 16:14:50 【问题描述】:

我有一个关于 WCF 模拟的问题。我想连接到客户端应用程序调用的 WCF Windows 服务上的数据库。与数据库的连接应使用运行服务的帐户来完成。但我想验证对 WCF 服务的调用是否来自受信任的来源(验证客户端应用程序的用户是否是域的经过身份验证的用户)。

您建议我使用哪种安全措施?

我尝试过模拟,但在尝试从 Windows 服务连接到数据库时出现此错误:

System.Data.SqlClient.SqlException:用户“NT AUTHORITY\ANONYMOUS LOGON”登录失败。

配置字符串是这样的:

server=myServer;初始目录=myDatabase;Integrated Security=True

服务的 WCF 配置如下所示:

<system.serviceModel>
<services>
  <service name="MyNamespace.MyService"
           behaviorConfiguration="TransfertServiceBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8095/MyNamespace.MyService"/>
      </baseAddresses>
    </host>
    <endpoint address=""
              binding="netTcpBinding"
              bindingConfiguration="TransactionalBinding"
              contract="myContract" />
    <endpoint address="mex"
              binding="mexTcpBinding"
              contract="IMetadataExchange" />
  </service>
</services>

<bindings>
  <netTcpBinding>
    <binding name="TransactionalBinding"
             transferMode="Streamed" transactionFlow="true" maxReceivedMessageSize="1000000000">
      <readerQuotas maxDepth="10000" maxStringContentLength="1000000000"
              maxArrayLength="1000000000" maxBytesPerRead="10000" maxNameTableCharCount="10000" />
      <security mode="Transport" />
    </binding>

  </netTcpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="TransfertServiceBehavior">
      <serviceMetadata httpGetEnabled="False"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
      <serviceAuthorization impersonateCallerForAllOperations="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

客户端应用程序上的配置如下所示:

<system.serviceModel>
<bindings>
  <netTcpBinding>
    <binding name="NetTcpBinding_Client" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      transactionFlow="true" transferMode="Streamed" transactionProtocol="OleTransactions"
      hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="1000000000"
      maxBufferSize="1000000000" maxConnections="10" maxReceivedMessageSize="65536">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1000000000"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
        enabled="false" />
      <security mode="Transport">
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
        <message clientCredentialType="Windows" />
      </security>
    </binding>
  </netTcpBinding>
</bindings>
<client>

  <endpoint address="net.tcp://localhost:8095/MyNamespace.MyService"
    binding="netTcpBinding" bindingConfiguration="NetTcpBinding_Client"
    contract="myContract" behaviorConfiguration="ImpersonationBehavior">
    <identity>
      <userPrincipalName value="myUsername@intra.myDomain.ca" />
    </identity>
  </endpoint>
</client>

<behaviors>
  <endpointBehaviors>
    <behavior name="ImpersonationBehavior">
      <clientCredentials>
        <windows allowedImpersonationLevel="Impersonation" />
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

【问题讨论】:

【参考方案1】:

如果您的 WCF 模拟,那么您必须为 WCF 帐户服务启用 Kerberos Constrained Delegation,另请参阅 Delegation and Impersonation with WCF。

详细说明Configure the WCF Service Identity Trusted for Constrained Delegation:

在域控制器上,启动 Microsoft 管理控制台 (MMC) Active Directory 用户和计算机管理单元。 在 MMC 管理单元的左窗格中,单击“计算机”节点。 在右侧窗格中,双击您的 WCF 服务器计算机以 显示“属性”对话框。 在 WCF 服务器的“属性”窗口的“委派”选项卡上 计算机,不信任委托的计算机被选择 默认。要使用约束委派,请选择信任此计算机 仅委托给指定的服务。您准确指定哪个 可以在底部窗格中访问一个或多个服务。 在信任此计算机以委派指定服务下 仅,保留默认选项“仅使用 Kerberos”。 单击“添加”按钮以显示“添加服务”对话框。 点击用户或计算机按钮。

在“选择用户或计算机”对话框中,键入您的名称 数据库服务器计算机(如果您将 SQL Server 作为系统运行)或 网络服务。

或者,如果您使用自定义运行 SQL Server 域帐户,请输入该帐户名称,然后单击确定。 您将看到为所选用户配置的所有 SPN 或 电脑帐户。要限制对 SQL Server 的访问,请选择 MSSQLSvc 服务,然后单击确定。

【讨论】:

非常感谢!这很有帮助。我猜这是实现最佳安全性的方法。【参考方案2】:

从您的服务配置中删除此行:

<serviceAuthorization impersonateCallerForAllOperations="true" />

这来自您的客户端配置:

<behaviors>
  <endpointBehaviors>
    <behavior name="ImpersonationBehavior">
      <clientCredentials>
        <windows allowedImpersonationLevel="Impersonation" />
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

模拟意味着所有操作都将在模拟用户的上下文中完成 = 服务的身份被替换为调用用户的身份。如果您的 SQL 服务器本地安装在运行 Windows 服务的计算机上,您对数据库的调用也将被模拟。

如果您关闭模拟,您将获得您想要的,因为在服务中执行将使用服务帐户,但服务将验证每个调用客户端。它由您的 netTcpBinding 配置完成,该配置使用 Windows 集成身份验证的传输安全性。

【讨论】:

为了清楚起见,第一个服务调用运行良好。但是随后此服务本身调用了第二个 WCF 远程服务,并且在第二个调用中出现此错误。

以上是关于WCF Windows 服务数据库连接和模拟问题的主要内容,如果未能解决你的问题,请参考以下文章

在 WCF 服务中使用模拟时 SQL 登录失败

自托管 WCF 服务和 basicHttpBinding:绑定不提供表示调用者的 Windows 标识

Windows 服务与托管 WCF 服务

在声明身份验证的 SharePoint 2010 中托管的 WCF 服务中的模拟

IIS托管WCF服务:集成测试和代码覆盖

WCF net.tcp - 目标机器拒绝连接