Пользовательская проверка входа в систему безопасности Windows

Я создаю приложение Xaml/C #и хочу, чтобы оно появлялось во всплывающем окне с запросом на вход.

Я хотел бы знать, возможно ли использовать CredUIPromptForWindowsCredentials.

  • Показать диалоговое окно безопасности Windows
  • Получить введенное имя пользователя и пароль
  • Выполнить пользовательскую проверку
  • Если проверка прошла успешно -> продолжить приложение
  • иначе, если проверка не удалась -> -сообщить пользователю неверного имени пользователя или пароля

Я уже просмотрел форму входа в систему безопасности Windows? и http://www.pinvoke.net/default.aspx/credui/creduipromptforwindowscredentials.html?diff=y, но они не объясняют, как обрабатывать проверку.

Мне бы очень хотелось небольшой пример, в котором, если пользователь вводит имя пользователя = "Bo" и пароль = "123", то все завершается успешно, иначе отображается сообщение об ошибке и пользователь может повторить попытку.

Приложение будет установлено на нескольких компьютерах.

Или это просто невозможно?

Обновление

Вдохновленный ответом на этот вопрос Показать диалоговое окно аутентификации в C #для Windows Vista/7

Я изменил код, чтобы он работал должным образом.

Обратите внимание, что часть проверки предназначена только для проверки концепции.

WindowsSecurityDialog.cs

 public class WindowsSecurityDialog
    {

       public string CaptionText { get; set; }
       public string MessageText { get; set; }

        [DllImport("ole32.dll")]
        public static extern void CoTaskMemFree(IntPtr ptr);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct CREDUI_INFO
        {
            public int cbSize;
            public IntPtr hwndParent;
            public string pszMessageText;
            public string pszCaptionText;
            public IntPtr hbmBanner;
        }


        [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("credui.dll", CharSet = CharSet.Auto)]
        private static extern int CredUIPromptForWindowsCredentials(ref CREDUI_INFO notUsedHere,
                                                                     int authError,
                                                                     ref uint authPackage,
                                                                     IntPtr InAuthBuffer,
                                                                     uint InAuthBufferSize,
                                                                     out IntPtr refOutAuthBuffer,
                                                                     out uint refOutAuthBufferSize,
                                                                     ref bool fSave,
                                                                     int flags);



        public bool ValidateUser()
        {
            var credui = new CREDUI_INFO
                                     {
                                         pszCaptionText = CaptionText,
                                         pszMessageText = MessageText
                                     };
            credui.cbSize = Marshal.SizeOf(credui);
            uint authPackage = 0;
            IntPtr outCredBuffer;
            uint outCredSize;
            bool save = false;


            const int loginErrorCode = 1326;    //Login Failed
            var authError = 0;

            while (true)
            {




                var result = CredUIPromptForWindowsCredentials(ref credui,
                                                               authError,
                                                               ref authPackage,
                                                               IntPtr.Zero,
                                                               0,
                                                               out outCredBuffer,
                                                               out outCredSize,
                                                               ref save,
                                                               1 /* Generic */);

                var usernameBuf = new StringBuilder(100);
                var passwordBuf = new StringBuilder(100);
                var domainBuf = new StringBuilder(100);

                var maxUserName = 100;
                var maxDomain = 100;
                var maxPassword = 100;
                if (result == 0)
                {
                    if (CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName,
                                                       domainBuf, ref maxDomain, passwordBuf, ref maxPassword))
                    {
                        //TODO: ms documentation says we should call this but i can't get it to work
                        //SecureZeroMem(outCredBuffer, outCredSize);

                        //clear the memory allocated by CredUIPromptForWindowsCredentials 
                        CoTaskMemFree(outCredBuffer);
                        var networkCredential = new NetworkCredential()
                                                {
                                                    UserName = usernameBuf.ToString(),
                                                    Password = passwordBuf.ToString(),
                                                    Domain = domainBuf.ToString()
                                                };

                        //Dummy Code replace with true User Validation
                        if (networkCredential.UserName == "Bo" && networkCredential.Password == "1234")
                            return true;
                        else //login failed show dialog again with login error
                        {
                            authError = loginErrorCode;
                        }



                    }
                }
                else return false;


            }
        }
    }

App.xaml.cs

protected override void OnStartup(StartupEventArgs e)
        {
            var windowsSecurityDialog = new WindowsSecurityDialog
                                            {
                                                CaptionText = "Enter your credentials",
                                                MessageText = "These credentials will be used to connect to YOUR APP NAME";
                                            };

            if (windowsSecurityDialog.ValidateUser())
                base.OnStartup(e);
        }

8
задан Community 23 May 2017 в 12:17
поделиться