MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Сквозная авторизация в AD"
Answer 872287
Как-то так:
//Reference: System.DirectoryServices.AccountManagement using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Security.Principal; using System.DirectoryServices.AccountManagement; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WindowsFormsApplication { static class Program { //Проверяет, авторизован ли пользователь в домене public static bool IsInDomain(string domain) { bool retval = false; NetJoinStatus status = NetJoinStatus.NetSetupUnknownStatus; IntPtr pDomain = IntPtr.Zero; int result = NetGetJoinInformation(null, out pDomain, out status); if (result != 0) throw new Win32Exception("NetGetJoinInformation failed"); if (pDomain != IntPtr.Zero) { string curr_domain = Marshal.PtrToStringUni(pDomain); if (status == NetJoinStatus.NetSetupDomainName && curr_domain.ToUpper().Trim() == domain.ToUpper().Trim()) { retval = true; } NetApiBufferFree(pDomain); } return retval; } //Выводит диалоговое окно ввода логина и пароля, и возвращает имя пользователя при успешной авторизации static string EnterCredentials(string domain) { bool save = false; int errorcode = 0; uint dialogReturn; uint authPackage = 0; IntPtr outCredBuffer; uint outCredSize; CREDUI_INFO credui = new CREDUI_INFO(); credui.cbSize = Marshal.SizeOf(credui); credui.pszCaptionText = "Авторизация"; credui.pszMessageText = "Введите логин и пароль"; credui.hwndParent = IntPtr.Zero; //Show dialog dialogReturn = CredUIPromptForWindowsCredentials(ref credui, errorcode, ref authPackage, (IntPtr)0, 0, out outCredBuffer, out outCredSize, ref save, 0x1 /*CREDUIWIN_GENERIC*/); if (dialogReturn != 0) return ""; //Cancel pressed var usernameBuf = new StringBuilder(100); var passwordBuf = new StringBuilder(100); var domainBuf = new StringBuilder(100); int maxUserName = 100; int maxDomain = 100; int maxPassword = 100; //Validate credentials if (CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName, domainBuf, ref maxDomain, passwordBuf, ref maxPassword)) { CoTaskMemFree(outCredBuffer); using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domain)) { bool valid; valid = context.ValidateCredentials(usernameBuf.ToString(), passwordBuf.ToString()); if (valid) return usernameBuf.ToString(); else return ""; } } else throw new ApplicationException("CredUnPackAuthenticationBuffer failed"); } /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); string domain = "Domain"; string user = Environment.UserName; bool logged = IsInDomain(domain); if (logged) { MessageBox.Show("Здравствуйте, " + user + ". Вы уже авторизованы в " + domain); } else { user = EnterCredentials(domain); if (user == "") { MessageBox.Show("Не удалось авторизоваться"); return; } else MessageBox.Show("Здравствуйте, " + user + ". Добро пожаловать в " + domain); } Application.Run(new Form1()); } // *** WINAPI Functions *** [DllImport("credui.dll", CharSet = CharSet.Unicode)] private static extern uint CredUIPromptForWindowsCredentials(ref CREDUI_INFO notUsedHere, int authError, ref uint authPackage, IntPtr InAuthBuffer, uint InAuthBufferSize, out IntPtr refOutAuthBuffer, out uint refOutAuthBufferSize, ref bool fSave, uint flags); [DllImport("credui.dll", CharSet = CharSet.Auto)] private static extern bool CredUnPackAuthenticationBuffer(int dwFlags, IntPtr pAuthBuffer, uint cbAuthBuffer, StringBuilder pszUserName, ref int pcchMaxUserName, StringBuilder pszDomainName, ref int pcchMaxDomainame, StringBuilder pszPassword, ref int pcchMaxPassword ); [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int NetGetJoinInformation(string server, out IntPtr domain, out NetJoinStatus status); [DllImport("Netapi32.dll")] public static extern int NetApiBufferFree(IntPtr Buffer); public enum NetJoinStatus { NetSetupUnknownStatus = 0, NetSetupUnjoined, NetSetupWorkgroupName, NetSetupDomainName } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct CREDUI_INFO { public int cbSize; public IntPtr hwndParent; public string pszMessageText; public string pszCaptionText; public IntPtr hbmBanner; } [DllImport("ole32.dll")] public static extern void CoTaskMemFree(IntPtr ptr); } }
Источники
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.