如何通过用户名和密码获取WindowsPrincipal

5
我正在使用WebAPI并将其托管在Katana中。我现在正在编写一些中间件,用于身份验证和授权。由于请求可能来自各种平台,因此我必须使用带SSL的基本身份验证。目前OAuth不是一个选项。中间件需要接收基本身份验证提供的用户名和密码,并验证用户是否为本地Windows组的成员。
现在我正在尝试找出如何创建WindowsPrincipal。如果我知道如何从用户名和密码创建WindowsPrincipal,那么我就知道如何完成其余部分。以下是我目前拥有的代码:
    //TODO
    WindowsPrincipal userPrincipal = null; //This is where I need to take the username and password and create a WindowsPrincipal
    Thread.CurrentPrincipal = userPrincipal;

    AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
    PrincipalPermission permission = new PrincipalPermission(null, "Local Group Name");
    permission.Demand();

我正在努力寻找一种好的方法,使用用户名和密码验证成员是否属于特定组。最好的方式是什么?提前感谢您的帮助。

1个回答

7

实际上,我认为您应该使用WindowsIdentity而不是WindowsPrincipal来获取这些信息。

要获取/模拟用户,您必须从advapi32.dll中调用LogonUser()函数:

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(
        string lpszUsername,
        string lpszDomain,
        string lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        out IntPtr phToken);

考虑到上述代码位于“Native”类中,模拟用户的方法如下:
var userToken = IntPtr.Zero;

var success = Native.LogonUser(
  "username", 
  "domain", 
  "password", 
  2, // LOGON32_LOGON_INTERACTIVE
  0, // LOGON32_PROVIDER_DEFAULT
  out userToken);

if (!success)
{
  throw new SecurityException("User logon failed");
}

var identity = new WindowsIdentity(userToken);

if(identity.Groups.Any(x => x.Value == "Group ID")) 
{
    // seems to be in the group!
} 

您可以在这里找到关于本机调用的更多信息:http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa378184%28v=vs.85%29.aspx

本机调用是IT技术中重要的一环。以上链接提供了更多关于本机调用的详细信息。


顺便提一下,如果您仍需要访问WindowsPrincipal,可以通过WindowsIdentity生成它:WindowsPrincipal principal = new WindowsPrincipal(identity); - pysco68
1
运行得非常好。感谢您的帮助!关于这种方法,我有一个最后的问题。我没有太多从托管代码调用本机代码的经验,想确保清理所有未管理的资源。看起来我应该在使用kernel32.dll中的CloseHandle()关闭userToken的句柄。除了与我所缺少的本机调用相关的任何其他清理工作吗? - r2_118
实际上,一旦您不再需要用户令牌,您只需调用CloseHandle()即可,无需执行其他操作。我相信WindowsIdentity的生命周期与令牌的生命周期没有绑定,但您可能想自己尝试一下! - pysco68

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接