Запросить windows авторизацию

159
05 апреля 2018, 11:43

Я хочу запросить ввод пароля пользователя, когда он нажимает на кнопку. Можете подсказать метод, который вызовет стандартное диалоговое окно windows, пользователь введёт пароль, и, если он верный, мне вернётся true? LogonUser похоже на то что мне нужно, хотя там и не появляется окошка

Answer 1

Для отображения диалогового окна можно использовать функцию CredUIPromptForWindowsCredentials, а для проверки логина и пароля - PrincipalContext (добавить ссылку на System.DirectoryServices.AccountManagement).

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.DirectoryServices.AccountManagement;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WinformsTest
{
    public partial class Form1 : Form
    {
        //https://www.pinvoke.net/default.aspx/credui.creduipromptforwindowscredentials
        [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("ole32.dll")]
        public static extern void CoTaskMemFree(IntPtr ptr);
        public Form1()
        {
            InitializeComponent();
        }
        bool CheckCredentials()
        {
            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 = this.Handle;
            //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 false; //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.Machine)) 
                {
                    bool valid;
                    try
                    {
                        valid = context.ValidateCredentials(usernameBuf.ToString(), passwordBuf.ToString());
                    }
                    catch (System.DirectoryServices.AccountManagement.PrincipalOperationException ex)
                    {
                        MessageBox.Show(ex.ToString(), "Ошибка");
                        valid = false;
                    }
                    return valid;
                }
            }
            else throw new ApplicationException("CredUnPackAuthenticationBuffer failed");
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (!CheckCredentials()) MessageBox.Show("Не удалось авторизоваться");                        
        }
    }
    [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;
    }

}
READ ALSO
В C# после десериализации JSON свойство равно Null

В C# после десериализации JSON свойство равно Null

Всем приветДесериализовал JSON, но почему-то при попытке вывести какие-либо значения, получаю либо Null, либо исключение

177
Загрузка/удаление записей из базы и вывод в WPF

Загрузка/удаление записей из базы и вывод в WPF

Есть база данныхДержать все записи в памяти очень ресурсно затратно

144