Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get WindowsPrincipal from username and password

I am using WebAPI and hosting it with Katana. I'm writing some middleware right now that will be used for authentication and authorization. I have to use basic authentication with SSL because requests could be coming from a variety of platforms. OAuth is also not an option at this time. The middleware needs to take the username and password provided from basic authentication and validate that the user is a member in a local Windows Group.

Right now I am trying to figure out how to create a WindowsPrincipal. If I could figure how to create a WindowsPrincipal from a username and password I know how to do the rest. Here is what I have right now.

    //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();

I am struggling to find a good way to use the username and password to validate that the member is part of a specific group. What is the best way to do this? Thanks for the help in advance.

like image 262
r2_118 Avatar asked Mar 18 '23 10:03

r2_118


1 Answers

Actually I think that you should be using a WindowsIdentity instead of the WindowsPrincipal to get that infromation.

To aquire/impersonate the user you must p/invoke LogonUser() from the advapi32.dll:

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

Considering that the above is in the class "Native", impersonating the user would be as following:

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!
} 

You can find additional information about the native call here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184%28v=vs.85%29.aspx

like image 129
pysco68 Avatar answered Apr 02 '23 17:04

pysco68