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

发布于 2024-11-29 07:51:35 字数 3858 浏览 0 评论 0原文

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

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

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

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

配置字符串是这样的:

server=myServer;初始目录=myDatabase;集成安全性=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="[email protected]" />
    </identity>
  </endpoint>
</client>

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

I have a question regarding the Impersonation on WCF. I'd like to connect to a DB on a WCF Windows service that is called by a client application. The connection to the DB should be done using the account under which the service runs. BUT I'd like to validate that the call to the WCF service is made from a trusted source (validate that the user of the client app is a autenticated user of the domain).

What is the kind security you would advise me to use ?

I tried Impersonation, but I get this error when trying to connect to the DB from the windows service :

System.Data.SqlClient.SqlException: Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.

The configuration string is like this :

server=myServer;Initial Catalog=myDatabase;Integrated Security=True

The WCF configuration of the service looks like this :

<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>

The configuration on the client app looks like this :

<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="[email protected]" />
    </identity>
  </endpoint>
</client>

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

唐婉 2024-12-06 07:51:35

如果您的 WCF 模拟,则必须启用 Kerberos 约束委派 对于 WCF 帐户服务,另请参阅 WCF 的委托和模拟

详细说明位于配置受约束委派信任的 WCF 服务标识

  • 在域控制器上启动 Microsoft 管理控制台
    (MMC) Active Directory 用户和计算机管理单元。
  • 在 MMC 管理单元的左窗格中,单击“计算机”节点。
  • 在右侧窗格中,双击您的 WCF 服务器计算机以
    显示“属性”对话框。
  • 在 WCF 服务器“属性”窗口的“委派”选项卡上
    计算机,不信任该计算机进行委派由
    默认。要使用约束委派,请选择“信任此计算机”
    仅委托给指定的服务。您精确指定哪个
    可以在底部窗格中访问一个或多个服务。
  • 下面信任此计算机以委派指定的服务
    仅,保持选中默认选项“仅使用 Kerberos”。
  • 单击“添加”按钮以显示“添加服务”对话框。
  • 点击“用户或计算机”按钮。
  • 在“选择用户或计算机”对话框中,键入您的名称
    数据库服务器计算机(如果您将 SQL Server 作为系统运行)或
    网络服务。

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

If your WCF impersonates then you must enable Kerberos Constrained Delegation for the WCF account service, see also Delegation and Impersonation with WCF.

Detailed instructions at Configure the WCF Service Identity Trusted for Constrained Delegation:

  • On the domain controller, start the Microsoft Management Console
    (MMC) Active Directory Users and Computers snap-in.
  • In the left pane of the MMC snap-in, click the Computers node.
  • In the right pane, double-click your WCF server computer to
    display the Properties dialog box.
  • On the Delegation tab of the Properties window for the WCF server
    computer, Do not trust the computer for delegation is selected by
    default. To use constrained delegation, select Trust this computer for
    delegation to specified services only. You specify precisely which
    service or services can be accessed in the bottom pane.
  • Beneath Trust this computer for delegation to specified services
    only, keep the default option Use Kerberos only selected.
  • Click the Add button to display the Add Services dialog box.
  • Click the Users or computers button.
  • In the Select Users or Computers dialog box, type the name of your
    database server computer if you are running SQL Server as System or
    Network Service.

    Alternatively, if you are running SQL Server by using a custom
    domain account, enter that account name instead and then click OK.
    You will see all the SPNs configured for the selected user or
    computer account. To restrict access to SQL Server, select the
    MSSQLSvc service, and then click OK.

清欢 2024-12-06 07:51:35

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

<serviceAuthorization impersonateCallerForAllOperations="true" />

并从您的客户端配置中删除此行:

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

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

如果您关闭模拟,您将得到您想要的东西,因为服务中的执行将使用服务帐户,但服务将验证每个调用客户端。这是通过使用传输安全性和 Windows 集成身份验证的 netTcpBinding 配置来完成的。

Remove this line from your service configuration:

<serviceAuthorization impersonateCallerForAllOperations="true" />

and this from your client configuration:

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

Impersonation means that all operations will be done withing context of impersonated users = identity of the service is replaced with the identity of calling user. If your SQL server is installed locally on the machine where your Windows service is running your calls to database will be impersonated as well.

If you turn off impersonation you will have exactly what you want because execution in the service will use service account but service will authenticate each calling client. It is done by your netTcpBinding configuration which uses transport security with Windows integrated authentication.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文