【问题标题】:How do I pass credentials to a machine so I can use Microsoft.Win32.RegistryKey.OpenRemoteBaseKey() on it?如何将凭据传递给计算机,以便可以在其上使用 Microsoft.Win32.RegistryKey.OpenRemoteBaseKey()?
【发布时间】:2011-02-02 05:54:38
【问题描述】:

This .NET API 如果我尝试在与我在同一个域中的计算机上打开注册表(并且我的登录用户在目标计算机上具有管理员权限),则可以正常工作。

如果它是一台具有不同本地管理用户(我确实有密码)的域外计算机,那就很棘手了。

在调用 OpenRemoteBaseKey() 之前,我尝试使用 WNetUseConnection()(在过去我想要读取远程磁盘文件的情况下,这对我很有帮助),但没有骰子 - 我被拒绝访问例外。

显然,我必须通过其他方式传递凭据,但如何?

【问题讨论】:

    标签: c# .net registry credentials remote-access


    【解决方案1】:

    我在电脑上成功访问文件的代码如下:

        #region imports 
            [DllImport("advapi32.dll", SetLastError = true)] 
            private static extern bool LogonUser(string 
            lpszUsername, string lpszDomain, string lpszPassword, 
            int dwLogonType, int dwLogonProvider, ref 
    IntPtr phToken); 
    
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, 
            SetLastError = true)] 
            private static extern bool CloseHandle(IntPtr handle 
            ); 
    
            [DllImport("advapi32.dll", CharSet = CharSet.Auto, 
            SetLastError = true)] 
            public extern static bool DuplicateToken(IntPtr 
            existingTokenHandle, 
            int SECURITY_IMPERSONATION_LEVEL, ref IntPtr 
            duplicateTokenHandle); 
            #endregion 
            #region logon consts 
            // logon types 
            const int LOGON32_LOGON_INTERACTIVE = 2; 
            const int LOGON32_LOGON_NETWORK = 3; 
            const int LOGON32_LOGON_NEW_CREDENTIALS = 9; 
    
            // logon providers 
            const int LOGON32_PROVIDER_DEFAULT = 0; 
            const int LOGON32_PROVIDER_WINNT50 = 3; 
            const int LOGON32_PROVIDER_WINNT40 = 2; 
            const int LOGON32_PROVIDER_WINNT35 = 1; 
            #endregion 
    

    然后对于部分签名,只需使用:

            IntPtr token = IntPtr.Zero; 
    
            bool isSuccess = LogonUser("username", "domain", "password", 
            LOGON32_LOGON_NEW_CREDENTIALS, 
            LOGON32_PROVIDER_DEFAULT, ref token); 
            using (WindowsImpersonationContext person = new WindowsIdentity(token).Impersonate()) 
            { 
            //do your thing 
             person.Undo(); 
            } 
    

    如您所见,“Undo()”将使您不再以该用户身份登录。所以在你完成之前不要使用它。但不要忘记使用它!

    【讨论】:

    • 我能否将“token”变量保留很长时间,然后使用相同的token在不同的地方使用“using/Undo()”块?”
    • 我是这么认为的。实际登录的是 Impersonate。我使用的是“GetImpersonation()”,它返回像上面一样的 WindowsImpersonationContext
    • 但是 person.Undo() 不会使 person 变量无法用于将来的访问吗?我的计划是调用 LogonUser(),保留“token”指针,然后使用与您的完全一样的各种 using 块,每个块都创建一个新的 WindowsImpersonationContext 对象。
    • 或者我可能不会每次都调用 Undo(),只是使用(person) { something(); },然后使用(人){ something_else(); },然后当我确定不再需要连接时,person.Undo()?
    • 那么你每次都会处理你的对象并且无法撤消它(我认为)。也许相反,只是让一个人挂起并且没有“使用”,而是显式调用 dispose
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多