为什么在 WCF 中远程运行的 wmi 查询与本地运行的 wmi 查询会得到不同的结果?
我正在 WCF 服务中通过 csharp/.net 查询打印机。当在本地调用时(即从本地计算机运行的客户端),它返回一组打印机。远程调用时,它会调用不同的话机。
wcf 服务设置为接受并模拟使用在创建客户端时传递的凭据。
我通过远程调试注意到的主要区别是调用中的身份验证类型:
WindowsIdentity.GetCurrent()
远程调用时为 Kerberos,本地调用时为 Neogotiate。
这是代码的快速示例:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public List<string> GetAvailablePrinters()
{
List<string> retval = new List<string>();
using (ManagementClass printerClass = new ManagementClass("win32_printer"))
{
ManagementObjectCollection printers = printerClass.GetInstances();
foreach (ManagementObject printer in printers)
{
if ((bool)printer["Shared"] == true)
retval.Add((string)printer["Name"]);
}
}
return retval;
}
两个调用都成功,但是我在本地获得了正确的列表,而在远程却没有获得任何信息。
这是两者的并排:
测试可执行文件在本地服务器上运行:
{System.Security.Principal.WindowsIdentity}
AuthenticationType: "Negotiate"
Groups: {System.Security.Principal.IdentityReferenceCollection}
ImpersonationLevel: Impersonation
IsAnonymous: false
IsAuthenticated: true
IsGuest: false
IsSystem: false
m_authType: null
m_groups: {System.Security.Principal.IdentityReferenceCollection}
m_impersonationLevel: Impersonation
m_isAuthenticated: 1
m_name: null
m_owner: null
m_safeTokenHandle: {Microsoft.Win32.SafeHandles.SafeTokenHandle}
m_user: {xxxxx}
Name: "adomain\\auser"
Owner: {xxxxx}
Token: token number
TokenHandle: {Microsoft.Win32.SafeHandles.SafeTokenHandle}
User: {xxxxxxxx}
相同的可执行文件远程运行
{System.Security.Principal.WindowsIdentity}
AuthenticationType: "Kerberos"
Groups: {System.Security.Principal.IdentityReferenceCollection}
ImpersonationLevel: Impersonation
IsAnonymous: false
IsAuthenticated: true
IsGuest: false
IsSystem: false
m_authType: null
m_groups: {System.Security.Principal.IdentityReferenceCollection}
m_impersonationLevel: Impersonation
m_isAuthenticated: 1
m_name: null
m_owner: null
m_safeTokenHandle: {Microsoft.Win32.SafeHandles.SafeTokenHandle}
m_user: {xxxxx}
Name: "adomain\\auser"
Owner: {differnt owner}
Token: different Token number
TokenHandle: {Microsoft.Win32.SafeHandles.SafeTokenHandle}
User: {xxxxxx}
I'm querying printers via csharp/.net inside a WCF service. When called locally (i.e. a client run from the local machine) It returns one set of printers. When called remotely, it calls a different set.
The wcf service is setup to accept and impersonate using the credentials passed in the creation of the client.
The major difference I've notice via remote debugging is the Authentication Type in the call to:
WindowsIdentity.GetCurrent()
Which is Kerberos when called remotely and Neogotiate when called locally.
Here is a quick sampling of code:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public List<string> GetAvailablePrinters()
{
List<string> retval = new List<string>();
using (ManagementClass printerClass = new ManagementClass("win32_printer"))
{
ManagementObjectCollection printers = printerClass.GetInstances();
foreach (ManagementObject printer in printers)
{
if ((bool)printer["Shared"] == true)
retval.Add((string)printer["Name"]);
}
}
return retval;
}
Both calls are succeeding, however I get the correct list locally, and nothing remotely.
Here is a side by side of the two:
Test Executable run on the local server:
{System.Security.Principal.WindowsIdentity}
AuthenticationType: "Negotiate"
Groups: {System.Security.Principal.IdentityReferenceCollection}
ImpersonationLevel: Impersonation
IsAnonymous: false
IsAuthenticated: true
IsGuest: false
IsSystem: false
m_authType: null
m_groups: {System.Security.Principal.IdentityReferenceCollection}
m_impersonationLevel: Impersonation
m_isAuthenticated: 1
m_name: null
m_owner: null
m_safeTokenHandle: {Microsoft.Win32.SafeHandles.SafeTokenHandle}
m_user: {xxxxx}
Name: "adomain\\auser"
Owner: {xxxxx}
Token: token number
TokenHandle: {Microsoft.Win32.SafeHandles.SafeTokenHandle}
User: {xxxxxxxx}
Same executable run remotely
{System.Security.Principal.WindowsIdentity}
AuthenticationType: "Kerberos"
Groups: {System.Security.Principal.IdentityReferenceCollection}
ImpersonationLevel: Impersonation
IsAnonymous: false
IsAuthenticated: true
IsGuest: false
IsSystem: false
m_authType: null
m_groups: {System.Security.Principal.IdentityReferenceCollection}
m_impersonationLevel: Impersonation
m_isAuthenticated: 1
m_name: null
m_owner: null
m_safeTokenHandle: {Microsoft.Win32.SafeHandles.SafeTokenHandle}
m_user: {xxxxx}
Name: "adomain\\auser"
Owner: {differnt owner}
Token: different Token number
TokenHandle: {Microsoft.Win32.SafeHandles.SafeTokenHandle}
User: {xxxxxx}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您尝试列出的打印机似乎是运行 WCF 服务的计算机的远程打印机。模拟仅允许您访问被调用计算机上可用的本地资源。这篇关于 WCF 中的模拟和委派的 MSDN 好文章应该可以帮助您继续下去正确的轨道。您需要实现委派以列出 WCF 服务中的远程资源,或者根本不使用委派并使 WCF 服务在可以列出远程打印机的域帐户下运行。
It seems that the printers you are trying to list are remote printers to the machine running the WCF service. Impersonation only lets you access local resources available on the machine being called. This good MSDN article on impersonation and delegation in WCF should get you going on the right track. You'll either need to implement delegation to list remote resources from the WCF service or not use delegation at all and make the WCF service run under a domain account that can list the remote printers.