模拟示例演示如何在服务中模拟调用方应用程序,以便服务代表调用方访问系统资源。
此示例基于 自托管 示例。 服务和客户端配置文件与 自承载 示例的配置文件相同。
注释
本示例的设置过程和生成说明位于本主题末尾。
服务代码已被修改,这样服务中的 Add
方法可以如以下示例代码所示,使用 OperationBehaviorAttribute 来冒用调用方的身份。
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public double Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
DisplayIdentityInformation();
return result;
}
因此,执行线程的安全上下文将在进入 Add
方法之前进行切换以模拟调用方,并在退出该方法时恢复。
DisplayIdentityInformation
以下示例代码中显示的方法是显示调用方标识的实用工具函数。
static void DisplayIdentityInformation()
{
Console.WriteLine("\t\tThread Identity :{0}",
WindowsIdentity.GetCurrent().Name);
Console.WriteLine("\t\tThread Identity level :{0}",
WindowsIdentity.GetCurrent().ImpersonationLevel);
Console.WriteLine("\t\thToken :{0}",
WindowsIdentity.GetCurrent().Token.ToString());
return;
}
服务 Subtract
上的方法通过命令式调用模仿调用方,如以下示例代码所示。
public double Subtract(double n1, double n2)
{
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
Console.WriteLine("Before impersonating");
DisplayIdentityInformation();
if (ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Impersonation ||
ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Delegation)
{
// Impersonate.
using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
{
// Make a system call in the caller's context and ACLs
// on the system resource are enforced in the caller's context.
Console.WriteLine("Impersonating the caller imperatively");
DisplayIdentityInformation();
}
}
else
{
Console.WriteLine("ImpersonationLevel is not high enough to perform this operation.");
}
Console.WriteLine("After reverting");
DisplayIdentityInformation();
return result;
}
请注意,在本例中,并未针对整个调用模拟调用方,而只是针对调用的一部分来模拟调用方。 通常,针对最小范围进行模拟比针对整个操作进行模拟更可取。
其他方法不能模拟调用方。
已修改客户端代码以将模拟级别设置为 Impersonation。 客户端通过使用TokenImpersonationLevel枚举来指定服务所用的模拟级别。 枚举支持以下值: None、 Anonymous、 Identification和 ImpersonationDelegation。 若要在使用 Windows ACL 保护的本地计算机上访问系统资源时执行访问检查,必须设置为 Impersonation模拟级别,如以下示例代码所示。
// Create a client with given client endpoint configuration
CalculatorClient client = new CalculatorClient();
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
运行示例时,作请求和响应会显示在服务和客户端控制台窗口中。 在每个控制台窗口中按 Enter 可以关闭服务和客户端。
注释
服务必须在管理帐户下运行,或者必须向其运行的帐户授予向 HTTP 层注册 http://localhost:8000/ServiceModelSamples
URI 的权限。 可以通过使用 Httpcfg.exe 工具设置命名空间预留来授予此类权限。
注释
在运行 Windows Server 2003 的计算机上,仅当 Host.exe 应用程序具有模拟权限时,才支持模拟。 (默认情况下,只有管理员才具有此权限。若要将此权限添加到运行服务的帐户,请转到 管理工具,打开 本地安全策略,打开 本地策略,单击 “用户权限分配”,然后在 身份验证后选择“模拟客户端 ”,然后双击 “属性 ”以添加用户或组。
设置、生成和运行示例
确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。
若要生成解决方案的 C# 或 Visual Basic .NET 版本,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。
若要在单台计算机或跨计算机配置中运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。
为了演示服务模拟调用方,请在与服务所运行帐户不同的帐户下运行客户端。 为此,请在命令提示符处键入:
runas /user:<machine-name>\<user-name> client.exe
然后系统会提示输入密码。 输入之前指定的帐户的密码。
运行客户端时,请注意它在用不同的凭据运行前后的标识。