RSS

[HowTo][C#] Authentifier un compte Windows dans une application Console

décembre 18, 2013

Si vous souhaitez utilisez un login/password d’un compte Windows et que vous souhaitez l’utilisez pour trouver les groupes ou vérifier qu’il est Administrateur, voici un exemple qui vous permettra de le faire simplement.

   1:  using System;
   2:  using System.Runtime.InteropServices;
   3:  using System.Security.Principal;
   4:   
   5:  namespace Automatic_Blank_Card
   6:  {
   7:      class Program
   8:      {
   9:          /// <summary>
  10:          /// Logon the <paramref name="lpszUsername"/> on the <paramref name="lpszDomain"/> according to the <paramref name="dwLogonProvider"/> and <paramref name="dwLogonType"/>
  11:          /// </summary>
  12:          /// <returns>True if the logon success, otherwise false</returns>
  13:          [DllImport("advapi32.dll", SetLastError = true)]
  14:          public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
  15:   
  16:          /// <summary>
  17:          /// Format the error message according to the <paramref name="dwMessageId"/> and <paramref name="dwLanguageId"/>
  18:          /// </summary>
  19:          /// <returns>1 if the format success, otherwise 0</returns>
  20:          [DllImport("kernel32.dll")]
  21:          public static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, ref IntPtr Arguments);
  22:   
  23:          /// <summary>
  24:          /// Close the unmanaged object to free memory and GAC
  25:          /// </summary>
  26:          [DllImport("kernel32.dll", SetLastError = true)]
  27:          [return: MarshalAs(UnmanagedType.Bool)]
  28:          static extern bool CloseHandle(IntPtr hObject);
  29:   
  30:   
  31:          public static string GetErrorMessage(int errorCode)
  32:          {
  33:              const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x100;
  34:              const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x200;
  35:              const int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
  36:   
  37:              const int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
  38:              const int msgSize = 255;
  39:   
  40:              string lpMsgBuf = null;
  41:              
  42:              var lpSource = IntPtr.Zero;
  43:              var lpArguments = IntPtr.Zero;
  44:              var returnVal = FormatMessage(dwFlags, ref lpSource, errorCode, 0, ref lpMsgBuf, msgSize, ref lpArguments);
  45:   
  46:              if (returnVal == 0)
  47:                  throw new Exception("Failed to format message for error code " + errorCode + ". ");
  48:              return lpMsgBuf;
  49:   
  50:          }
  51:   
  52:          private static string GetString(bool secured)
  53:          {
  54:              var result = string.Empty;
  55:              ConsoleKeyInfo key;
  56:              do
  57:              {
  58:                  key = Console.ReadKey(true);
  59:                  if (key.Key != ConsoleKey.Backspace)
  60:                  {
  61:                      if (secured)
  62:                      {
  63:                          Console.Write("*");
  64:                      }
  65:                      else
  66:                      {
  67:                          Console.Write(key.KeyChar);
  68:                      }
  69:                      result += key.KeyChar;
  70:                  }
  71:                  else
  72:                  {
  73:                      Console.Write("b");
  74:                  }
  75:              } 
  76:              while (key.Key != ConsoleKey.Enter);
  77:   
  78:              Console.WriteLine(string.Empty);
  79:   
  80:              return result;
  81:          }
  82:   
  83:          static void Main(string[] args)
  84:          {
  85:              Authenticate();
  86:              Console.ReadLine();
  87:          }
  88:   
  89:          static void Authenticate()
  90:          {
  91:              var userName = "n";
  92:              var pwd = "n";
  93:   
  94:              try
  95:              {
  96:                  const int LOGON32_PROVIDER_DEFAULT = 0;
  97:                  const int LOGON32_PROVIDER_WINNT50 = 3;
  98:   
  99:                  const int LOGON32_LOGON_INTERACTIVE = 2;
 100:                  const int LOGON32_LOGON_NETWORK = 3;
 101:                  const int LOGON_TYPE_NEW_CREDENTIALS = 9;
 102:   
 103:                  IntPtr tokenHandle;
 104:                  bool result;
 105:                  do
 106:                  {
 107:                      var machineName = Environment.UserDomainName;
 108:   
 109:                      //For DOMAIN authentication, prefers use LOGON_TYPE_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50 recommended by MSDN
 110:                      //NOTE: userName AND pwd is useless because the authenticationType is Negotiate so will be deduced directly
 111:                      //NOTE: Use 'n' in userName and pwd instead of 'string.Empty' to validate the entry parameters
 112:                      result = LogonUser(userName, machineName, pwd, LOGON_TYPE_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, out tokenHandle);
 113:                      //For LOCAL authentication
 114:                      //Console.Write("Username : " + machineName + "/");
 115:                      //userName = GetString(false);
 116:                      //Console.Write("Password : ");
 117:                      //pwd = GetString(true);
 118:                      //result = LogonUser(userName, machineName, pwd, LOGON_TYPE_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, out tokenHandle);
 119:                      if (!result)
 120:                      {
 121:                          var ret = Marshal.GetLastWin32Error();
 122:                          Console.WriteLine(GetErrorMessage(ret));
 123:                          CloseHandle(tokenHandle);
 124:                      }
 125:                  } while (!result);
 126:   
 127:                  var newId = new WindowsIdentity(tokenHandle);
 128:                  var userperm = new WindowsPrincipal(newId);
 129:   
 130:                  Console.WriteLine(userperm.IsInRole(WindowsBuiltInRole.Administrator)
 131:                                          ? "Access Granted. User is admin"
 132:                                          : "Access Granted. User is not admin");
 133:   
 134:                  CloseHandle(tokenHandle);
 135:              }
 136:              catch (Exception ex)
 137:              {
 138:                  Console.WriteLine("Exception occurred. " + ex.Message);
 139:              }
 140:          }
 141:      }
 142:  }

Il peut bien évidemment être améliorer et je vous invites à le faire 😉

 

Posted by on 18 décembre 2013 in .Net, C#.Net, Codes, Programmation, Tutoriel

Commentaires fermés sur [HowTo][C#] Authentifier un compte Windows dans une application Console

Comments are closed.