15

I am trying develop a simple web service to authenticate users of a desktop application using the windows identity framework, at present I am passing the token generated by WindowsIdentity.GetCurrent().Token via a post variable (it is encrypted and ssl'd, Windows authentication is not an option given the layout of our domain's and the configuration of the server). I am passing the token back fine and converting it back to an IntPtr.

I am at a lost as to how to validate the token to ensure that it was generated by a particular Active Directory (or any for that matter). I have tried to create a new WindowsIdentity instance given the token however that just results in an Exception (message: Invalid token for impersonation - it cannot be duplicated).

If anyone can provide any help or even hints I would greatly appreciated, thanks in advance.

techvice
  • 1,315
  • 1
  • 12
  • 24
mitchellsg
  • 486
  • 5
  • 13
  • Would it be possible to just use the token and leave the validation to Windows when you use the token to access a resource? – Emond Jun 12 '14 at 07:18
  • 2
    In my case I'm using a custom socket client/server solution where I want to authenticate users using windows authentication. Hence I need to transport a token or similar to the server for authentication, but I do not understand how. MSDN isn't very helpful. – jgauffin Jun 12 '14 at 07:20
  • Are the client and server on the same domain? Does the client authenticate to the domain when logging into windows? – Mike Hixson Jun 17 '14 at 17:23
  • I assume that you are looking for an Active Federation solution, some info about that can be found in this link http://msdn.microsoft.com/en-us/magazine/ee335707.aspx – Frode Nilsen Jun 18 '14 at 06:56
  • @MikeHixson: You are free to give an answer when they are. – jgauffin Jun 18 '14 at 12:01
  • @FrodeNilsen: Yes, but without WCF – jgauffin Jun 18 '14 at 12:02
  • [try this](http://www.codeproject.com/Articles/29853/User-Login-For-WinForm-Applications) – Shubhojit Jul 03 '14 at 08:24
  • If I understand what you want, this question is similar: http://stackoverflow.com/q/15251906/2164198 - the answer is to use WInAPI DuplicateTokenEx to duplicate your token and serialize it. Then you can use it for validation. – Ivan Samygin Jul 09 '14 at 10:22

2 Answers2

1
public bool DoesUserExist(string userName)
{
    using (var domainContext = new PrincipalContext(ContextType.Domain, "DOMAIN"))
    {
        using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName))
        {
            return foundUser != null;
        }
    }
}

To achieve checking for if a user exists. This comes from the System.DirectoryServices.AccountManagement namespace and assembly.

Just pass in your username which you can get from WindowsIdentity.GetCurrent() and this will return a true/false if a user if in your usergroup. (replace DOMAIN with your needed group name.)

benka
  • 4,732
  • 35
  • 47
  • 58
esre
  • 87
  • 9
0

Well,

If I understand correctly your question, I know it's possible to do it doing direct API Calls. The LogonUser in the advapi32.dll is the answer. The following snippet worked for me

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

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CloseHandle(IntPtr hObject);

    public static bool Authenticate(string userName, string password, string domain)
    {
        IntPtr token;
        LogonUser(userName, domain, password, 2, 0, out token);

        bool isAuthenticated = token != IntPtr.Zero;

        CloseHandle(token);

        return isAuthenticated;
    }

    public static IntPtr GetAuthenticationHandle(string userName, string password, string domain)
    {
        IntPtr token;
        LogonUser(userName, domain, password, 2, 0, out token);
        return token;
    }


}
Eric Lemes
  • 561
  • 3
  • 10