使用 TCP 信道进行身份验证

本主题介绍一项传统技术,保留该技术是为了向后兼容现有的应用程序,不建议对新的开发使用该技术。现在应该使用  Windows Communication Foundation (WCF) 来开发分布式应用程序。

TCP 信道直接支持身份验证和模拟。本主题介绍如何配置客户端和服务器信道。

通过设置关联的 TcpServerChannelTcpClientChannel 对象的属性,.NET Framework 允许远程对象的服务器对调用方进行身份验证和模拟。

服务器配置

若要配置 TCP 服务器信道以对远程调用方进行身份验证,请将 TCP 信道上的 secure 属性设置为 true,如下面的配置文件所示。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.runtime.remoting>
        <application>
            <channels>
              <channel ref="tcp" secure="true" />
             </channels>
        </application>
    </system.runtime.remoting>
</configuration>
59hafwyt.note(zh-cn,VS.100).gif注意:
客户端信道上的 secure 属性也必须设置为 true,以进行安全的通信。默认情况下,安全通信包括在服务器与客户端之间发送的数据的身份验证和加密。

对于通过身份验证的客户端,可通过以下方式访问其身份:首先获取 CurrentPrincipal,然后访问其 Identity 属性。模拟客户端的身份可以通过 GetCurrent 访问。然后可以根据需要执行您自己的授权。

若要配置 TCP 服务器信道以对远程调用方进行身份验证和模拟,请将 secure 属性和 impersonate 属性设置为 true,如下面的配置文件所示。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.runtime.remoting>
        <application>
            <channels>
              <channel ref="tcp" secure="true" impersonate="true" />
             </channels>
        </application>
    </system.runtime.remoting>
</configuration>
59hafwyt.note(zh-cn,VS.100).gif注意:
为了发生模拟,必须将客户端信道上的 tokenImpersonationLevel 属性设置为 impersonationdelegation。请注意,在服务器上,该属性称为 impersonate,但在客户端上,需要将 tokenImpersonationLevel 设置为 impersonation

59hafwyt.note(zh-cn,VS.100).gif注意:
所有进程都在 Windows Vista 上的标准用户帐户下运行。标准用户不能模拟管理员帐户。如果您有一个必须模拟管理员帐户的远程处理应用程序,则该应用程序必须在提升的特权下运行。

authorizationModule 属性允许服务器执行自己的授权。若要使用此属性,必须创建一个实现 IAuthorizeRemotingConnection 的类。此接口包含下列方法:

  • IsConnectingEndpointAuthorized:允许按 IP 地址对客户端进行授权。

  • IsConnectingIdentityAuthorized:允许按身份对客户端进行授权。

在服务器的配置文件中,将 authorizationModule 属性以字符串“namespace.class, assembly”的形式设置为实现 IAuthorizeRemotingConnection 的类,如下面的配置文件所示。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application name="AuthorizationApp">
      <service>
        <wellknown mode="SingleCall"
                   type="Server.SampleService, Server"
                   objectUri="Server.rem"/>
      </service>

      <channels>
        <channel ref="tcp" port="8001" secure="true" impersonate="true" authorizationModule="Server.AuthorizationModule,Server"/>
      </channels>
    </application>
  </system.runtime.remoting>
</configuration>

客户端配置

若要配置 TCP 客户端信道以对调用方进行身份验证,请将 TCP 信道上的 secure 属性设置为 true,如下面的配置文件所示。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.runtime.remoting>
        <application>
            <channels>
              <channel ref="tcp" secure="true" />
             </channels>
        </application>
    </system.runtime.remoting>
</configuration>
59hafwyt.note(zh-cn,VS.100).gif注意:
服务器信道上的 secure 属性也必须设置为 true,以进行安全的通信。默认情况下,安全通信包括在服务器与客户端间发送的数据的身份验证和加密。

若要配置 TCP 客户端信道使用模拟,请将 secure 属性设置为 true,将 tokenImpersonationLevel 属性设置为 impersonation,如下面的配置文件所示。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.runtime.remoting>
        <application>
            <channels>
              <channel ref="tcp" secure="true" tokenImpersonationLevel="impersonation"/>
             </channels>
        </application>
    </system.runtime.remoting>
</configuration>
59hafwyt.note(zh-cn,VS.100).gif注意:
为了发生模拟,必须将服务器信道上的 impersonate 属性设置为 true。请注意,在服务器上,该属性称为 impersonate,但在客户端上,需要将 tokenImpersonationLevel 设置为 impersonation

59hafwyt.note(zh-cn,VS.100).gif注意:
所有进程都在 Windows Vista 上的标准用户帐户下运行。标准用户不能模拟管理员帐户。如果您有一个必须模拟管理员帐户的远程处理应用程序,则该应用程序必须在提升的特权下运行。

tokenImpersonationLevel 可以设置为下表中一个值。

tokenImpersonationLevel 设置 说明

标识

服务器可以获取有关客户端的信息(如安全标识符和特权),但它无法模拟客户端。

模拟

服务器可以在其本地系统上模拟客户端的安全上下文。服务器无法在远程系统上模拟客户端。

委托

服务器可以在远程系统上模拟客户端。

默认情况下,TCP 客户端信道使用客户端进程运行所用的用户身份对自身进行身份验证。您可以通过设置 ___domainusernamepassword 属性来指定备用身份,如下面的代码示例所示。

RemotingConfiguration.Configure("Client.exe.config", true);
ISharedInterface remoteObject = (ISharedInterface)Activator.GetObject(
                typeof(ISharedInterface),
                "tcp://localhost:8001/server.rem");

// Set ___domain, username, and password
IDictionary props = ChannelServices.GetChannelSinkProperties(remoteObject);
props["___domain"] = "SomeDomain"; // only required if the user is a member of a ___domain
props["username"] = "SomeRemotingUser";
props["password"] = "Password123";

// Call method on remote object
remoteObject.HelloWorld("Hi Server");

您还可以在配置文件中指定 ___domainusernamepassword 属性。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.runtime.remoting>
        <application>
            <channels>
              <channel ref="tcp" 
                       secure="true" 
                       tokenImpersonationLevel="impersonation"
                       username="SomeRemotingUser"
                       password="Password123"
                       />
             </channels>
        </application>
    </system.runtime.remoting>
</configuration>
59hafwyt.note(zh-cn,VS.100).gif注意:
建议您不要在代码或配置中使用硬编码的用户名和密码。此处这样做的目的仅仅是为了便于说明。获取凭据的最佳方式是提示用户。

默认情况下,TCP 信道使用 NTLM 对调用方进行身份验证。若要强制信道使用 Kerberos,请将 servicePrincipalName 属性设置为服务运行所用的帐户,如下面的配置文件所示。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.runtime.remoting>
        <application>
            <channels>
              <channel ref="tcp" secure="true" tokenImpersonationLevel="impersonation"
                       servicePrincipalName="MyDomain\MyUserAccount"/>
          </channels>
        </application>
    </system.runtime.remoting>
</configuration>
59hafwyt.note(zh-cn,VS.100).gif注意:
Kerberos 需要访问 Active Directory 服务器。如果运行代码的计算机不是 Active Directory 域的成员,则改用 NTLM(默认值)。

另请参见

概念

加密和消息完整性
使用 HTTP 信道进行身份验证
使用 IPC 信道进行身份验证