在 wpf 应用程序中以调试模式检查当前用户凭据

Check current user credentials in debug mode in a wpf application

我正在尝试 运行 一个能够远程停止和启动服务的应用程序。该应用程序需要能够被没有管理员权限的用户使用,方法是模拟从加密数据库中读取用户名、密码和域的用户。

我目前面临的问题是我不确定模拟功能是否正常工作,因此我想在调试模式下检查哪个用户是当前用户。

这是我用来模拟用户的class:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Security.Permissions;

public class ImpersonateUser
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(
    String lpszUsername,
    String lpszDomain,
    String lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);
    private static IntPtr tokenHandle = new IntPtr(0);
    private static WindowsImpersonationContext impersonatedUser;
    // If you incorporate this code into a DLL, be sure to demand that it
    // runs with FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public void Impersonate(string domainName, string userName, string password)
    {
        //try
        {
            // Use the unmanaged LogonUser function to get the user token for
            // the specified user, domain, and password.
            const int LOGON32_PROVIDER_DEFAULT = 0;
        // Passing this parameter causes LogonUser to create a primary token.
        const int LOGON32_LOGON_INTERACTIVE = 2;
        tokenHandle = IntPtr.Zero;
        // ---- Step - 1
        // Call LogonUser to obtain a handle to an access token.
        bool returnValue = LogonUser(
        userName,
        domainName,
        password,
        LOGON32_LOGON_INTERACTIVE,
        LOGON32_PROVIDER_DEFAULT,
        ref tokenHandle); // tokenHandle - new security token
        if (false == returnValue)
        {
            int ret = Marshal.GetLastWin32Error();
            throw new System.ComponentModel.Win32Exception(ret);
        }
        // ---- Step - 2
        WindowsIdentity newId = new WindowsIdentity(tokenHandle);
        // ---- Step - 3
        {
            impersonatedUser = newId.Impersonate();
        }
    }
}
// Stops impersonation
public void Undo()
{
    impersonatedUser.Undo();
    // Free the tokens.
    if (tokenHandle != IntPtr.Zero)
    {
        CloseHandle(tokenHandle);
    }            
}        

}

这就是我尝试使用它的方式:

ImpersonateUser iu = new ImpersonateUser();
iu.Impersonate("[domain]","[username]","[password]");

try{
    ServiceController service = new ServiceController(serviceName, remoteComputer);
    service.Start();
}

iu.Undo(); 

但我不确定我插入的代码是否正确,或者我应该在编写代码时添加其他内容。

我找到了我要找的东西,只需调用 WindowsIdentity.GetCurrent().Name;其中 return 是当前正在使用该应用程序的用户,就像在我的情况下您使用的是 Impersonate() 一样,您需要将布尔值传递给调用,如下所示: WindowsIdentity.GetCurrent(true).Name; return 模拟用户。

编辑

我还想为可能面临相同问题的其他人添加一些内容,因为我试图检查远程计算机上用户的权限,所以这并不能解决问题。这就是为什么我使用另一个函数

static bool isAdmin(string username, string machinename)
{
using (PrincipalContext ctxMacine = new PrincipalContext(ContextType.Machine, machinename))
{
    using (PrincipalContext ctxDomain = new PrincipalContext(ContextType.Domain))
    {
        UserPrincipal up = UserPrincipal.FindByIdentity(ctxDomain, IdentityType.SamAccountName, username);
        GroupPrincipal gp = GroupPrincipal.FindByIdentity(ctxMacine, "Administrators");

        foreach (UserPrincipal usr in gp.GetMembers(true))
        {
            if (up != null)
            {
                if (up.SamAccountName.ToUpper() == usr.SamAccountName.ToUpper())
                {
                    return true;
                }
            }
        }
    }
}
return false;

}

像这样使用时:

 ImpersonateUser iu = new ImpersonateUser();
        iu.Impersonate(domain, userName, password);

string name = WindowsIdentity.GetCurrent(true).Name;
MessageBox.Show("CurrentUser: " + name + " " + isAdmin(name, remoteComputer));

iu.Undo();

将告诉您您正在模拟的当前用户是否对您尝试访问的远程计算机具有管理员权限。