我怎样才能可靠地检查客户端的身份,同时使得DCOM调用一个C#.net 3.5服务器? [英] How can I reliably check client identity whilst making DCOM calls to a C# .NET 3.5 Server?

查看:125
本文介绍了我怎样才能可靠地检查客户端的身份,同时使得DCOM调用一个C#.net 3.5服务器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个旧的Win32 C ++ DCOM服务器,我重写使用C#.NET 3.5。该客户端应用程序坐在远程Windows XP机器,并且还用C ++编写。这些客户端必须保持不变,所以我必须实现接口新的.NET对象。

I have an old Win32 C++ DCOM Server that I am rewriting to use C# .NET 3.5. The client applications sit on remote Windows XP machines and are also written in C++. These clients must remain unchanged, hence I must implement the interfaces on new .NET objects.

这已经完成,并正就成功了接口的实现,所有的呼叫都正确地正在从老客户到新的.NET对象。

This has been done, and is working successfully regarding the implementation of the interfaces, and all of the calls are correctly being made from the old clients to the new .NET objects.

不过,我有获得从DCOM客户端调用用户的身份问题。为了试图找出谁策动DCOM呼叫的用户,我已经在服务器上的以下code ...

However, I'm having problems obtaining the identity of the calling user from the DCOM Client. In order to try to identify the user who instigated the DCOM call, I have the following code on the server...

[DllImport("ole32.dll")]
static extern int CoImpersonateClient();

[DllImport("ole32.dll")]
static extern int CoRevertToSelf();

private string CallingUser
{
    get
    {
        string sCallingUser = null;

        if (CoImpersonateClient() == 0)
        {
            WindowsPrincipal wp = System.Threading.Thread.CurrentPrincipal as WindowsPrincipal;

            if (wp != null)
            {
                WindowsIdentity wi = wp.Identity as WindowsIdentity;

                if (wi != null && !string.IsNullOrEmpty(wi.Name))
                    sCallingUser = wi.Name;
            }

            if (CoRevertToSelf() != 0)
                ReportWin32Error("CoRevertToSelf");
        }
        else
            ReportWin32Error("CoImpersonateClient");

        return sCallingUser;
    }
}

private static void ReportWin32Error(string sFailingCall)
{
    Win32Exception ex = new Win32Exception();
    Logger.Write("Call to " + sFailingCall + " FAILED: " + ex.Message);
}

当我得到的 CallingUser 属性,返回值在最初几次是正确的,但是正确的用户名是确定的,后3或4个不同的用户有成功拨打的电话(与它不同,所以我不能更具体),进一步的用户似乎被认定为谁曾在早些时候呼吁用户。

When I get the CallingUser property, the value returned the first few times is correct and the correct user name is identified, however, after 3 or 4 different users have successfully made calls (and it varies, so I can't be more specific), further users seem to be identified as users who had made earlier calls.

我所注意到的是,前几个用户所自己的线程来处理他们的DCOM调用(即,从特定客户端的所有呼叫都用一个唯一的线程处理),然后随后的用户正由处理同一主题的早期用户,并调用后 CoImpersonateClient() CurrentPrincipal 匹配的初始用户的该线程的。

What I have noticed is that the first few users have their DCOM calls handled on their own thread (that is, all calls from a particular client are handled by a single unique thread), and then subsequent users are being handled by the same threads as the earlier users, and after the call to CoImpersonateClient(), the CurrentPrincipal matches that of the initial user of that thread.

要说明:

用户汤姆使它们由线程1( CurrentPrincipal 正确识别汤姆)

User Tom makes DCOM calls which are handled by thread 1 (CurrentPrincipal correctly identifies Tom)

用户迪克使得它们由线程2( CurrentPrincipal 正确识别迪克)

User Dick makes DCOM calls which are handled by thread 2 (CurrentPrincipal correctly identifies Dick)

用户哈利使它们由线3( CurrentPrincipal 正确识别哈利)

User Harry makes DCOM calls which are handled by thread 3 (CurrentPrincipal correctly identifies Harry)

用户鲍勃使它们由线3( CurrentPrincipal 错误地标识他为哈利)

User Bob makes DCOM calls which are handled by thread 3 (CurrentPrincipal incorrectly identifies him as Harry)

如您在本图中看到,来自客户端的哈利和Bob呼吁正在上线3处理,该服务器是确定调用客户端的哈利。

As you can see in this illustration, calls from clients Harry and Bob are being handled on thread 3, and the server is identifying the calling client as Harry.

有什么,我做错了什么? 是否有使用模仿秀这样的任何警告或限制? 有没有更好的或者不同的方式,我可以可靠地实现什么,我想干什么?

Is there something that I am doing wrong? Are there any caveats or restrictions on using Impersonations in this way? Is there a better or different way that I can RELIABLY achieve what I am trying to do?

所有帮助将不胜AP preciated。

All help would be greatly appreciated.

推荐答案

好了,我已经采取了不同的appropach,并finall拿出,似乎工作(测试8个不同的远程用户)的方法。

OK, so I've taken a different appropach, and finall come up with a method that seems to work (tested for 8 different remote users).

我已经抛弃了模拟路线赞成ClientBlankets的......

I've ditched the Impersonation route in favour of ClientBlankets...

[DllImport("ole32.dll")]
static extern int CoQueryClientBlanket(out IntPtr pAuthnSvc, out IntPtr pAuthzSvc,
    [MarshalAs(UnmanagedType.LPWStr)] out StringBuilder pServerPrincName, out IntPtr
    pAuthnLevel, out IntPtr pImpLevel, out IntPtr pPrivs, out IntPtr pCapabilities);

public static string CallingUser
{
    get
    {
        IntPtr pAthnSvc = new IntPtr();
        IntPtr pAthzSvc = new IntPtr();
        StringBuilder pServerPrincName = new StringBuilder();
        IntPtr pAuthnLevel = new IntPtr();
        IntPtr pImpLevel = new IntPtr();
        IntPtr pPrivs = new IntPtr();
        IntPtr pCaps = new IntPtr(4);
        string sCallingUser = string.Empty;

        try
        {
            CoQueryClientBlanket(out pAthnSvc,
                out pAthzSvc,
                out pServerPrincName,
                out pAuthnLevel,
                out pImpLevel,
                out pPrivs,
                out pCaps);
        }
        catch (Exception ex)
        {
            Logger.Write(ex.Message);
        }
        finally
        {
            sCallingUser = System.Runtime.InteropServices.Marshal.PtrToStringAuto(pPrivs);
        }

        return sCallingUser;
    }
}

使用CoCreateClientBlanket似乎有希望的结果,我能够可靠地获得主叫用户每次的标识,无论哪个线程用于处理该消息。

Using CoCreateClientBlanket seems to have the desired results, and I'm able to reliably obtain the identity of the calling user everytime, regardless of which thread is used to process the message.

这篇关于我怎样才能可靠地检查客户端的身份,同时使得DCOM调用一个C#.net 3.5服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆