You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET Framework 4.8的C# WPF应用中调用Windows内置登录验证本地用户?

在.NET Framework 4.8 WPF应用中调用Windows标准登录工具验证本地用户

核心方案概述

要实现调用Windows内置验证工具(支持Windows Hello PIN),无需自行开发验证逻辑,可通过两种系统原生方式实现:

  • 调用系统标准登录弹窗(支持密码、PIN、生物识别等Windows Hello方式)
  • 直接调用Windows Hello的PIN/生物识别验证接口

方案1:调用系统标准登录弹窗(CredUIPromptForWindowsCredentials)

这个API会弹出Windows原生的登录对话框,用户可选择用密码、PIN或生物识别验证,完全由系统处理凭证,无泄露风险。

代码实现

首先在WPF项目中添加互操作声明:

using System;
using System.Runtime.InteropServices;
using System.Windows;

public static class WindowsAuthHelper
{
    // 互操作声明
    [DllImport("credui.dll", CharSet = CharSet.Unicode)]
    private static extern int CredUIPromptForWindowsCredentials(ref CREDUI_INFO creditUR, int authError, ref uint authPackage, IntPtr InAuthBuffer, uint InAuthBufferSize, out IntPtr refOutAuthBuffer, out uint refOutAuthBufferSize, ref bool fSave, int flags);

    [DllImport("credui.dll", CharSet = CharSet.Unicode)]
    private static extern bool CredUnPackAuthenticationBuffer(int dwFlags, IntPtr pAuthBuffer, uint cbAuthBuffer, StringBuilder pszUserName, ref int pcchMaxUserName, StringBuilder pszDomainName, ref int pcchMaxDomainName, StringBuilder pszPassword, ref int pcchMaxPassword);

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

    // 验证方法
    public static bool ValidateLocalUser(IntPtr parentWindowHandle, string promptMessage)
    {
        CREDUI_INFO credUiInfo = new CREDUI_INFO();
        credUiInfo.cbSize = Marshal.SizeOf(credUiInfo);
        credUiInfo.hwndParent = parentWindowHandle;
        credUiInfo.pszMessageText = promptMessage;
        credUiInfo.pszCaptionText = "验证身份";

        uint authPackage = 0;
        IntPtr outAuthBuffer = IntPtr.Zero;
        uint outAuthBufferSize = 0;
        bool saveCredentials = false;
        int result = CredUIPromptForWindowsCredentials(ref credUiInfo, 0, ref authPackage, IntPtr.Zero, 0, out outAuthBuffer, out outAuthBufferSize, ref saveCredentials, 0x000010 /* CREDUIWIN_IN_CRED_ONLY - 只允许系统凭证 */);

        if (result != 0)
        {
            // 用户取消或验证失败
            return false;
        }

        try
        {
            // 解析验证结果
            StringBuilder userName = new StringBuilder(100);
            StringBuilder domainName = new StringBuilder(100);
            StringBuilder password = new StringBuilder(100);
            int userNameLen = userName.Capacity;
            int domainLen = domainName.Capacity;
            int passwordLen = password.Capacity;

            if (CredUnPackAuthenticationBuffer(0, outAuthBuffer, outAuthBufferSize, userName, ref userNameLen, domainName, ref domainLen, password, ref passwordLen))
            {
                // 可选:若需确认用户权限,可调用LogonUser API进一步验证
                return true;
            }
            return false;
        }
        finally
        {
            // 释放内存
            if (outAuthBuffer != IntPtr.Zero)
            {
                Marshal.ZeroFreeGlobalAllocUnicode(outAuthBuffer);
            }
        }
    }
}

在WPF窗口中调用

private void btnVerify_Click(object sender, RoutedEventArgs e)
{
    bool isAuthenticated = WindowsAuthHelper.ValidateLocalUser(new WindowInteropHelper(this).Handle, "请验证您的身份以继续操作");
    if (isAuthenticated)
    {
        MessageBox.Show("验证成功,可执行后续操作");
        // 这里执行你的请求操作
    }
    else
    {
        MessageBox.Show("验证失败或取消");
    }
}

方案2:直接调用Windows Hello PIN/生物识别验证

如果只想强制使用Windows Hello(PIN或指纹/面部识别),可调用WinRT的UserConsentVerifier接口,.NET Framework 4.8可通过互操作访问WinRT组件。

代码实现

首先右键项目 -> 添加 -> 引用 -> 浏览,找到并添加C:\Windows\System32\WinMetadata\Windows.Security.winmd组件。

然后编写验证方法:

using System;
using System.Threading.Tasks;
using System.Windows;
using Windows.Security.Credentials.UI;
using System.Runtime.InteropServices.WindowsRuntime;

public static class WindowsHelloHelper
{
    public static async Task<bool> VerifyUserWithHelloAsync(string promptMessage)
    {
        try
        {
            UserConsentVerificationResult result = await UserConsentVerifier.RequestVerificationAsync(promptMessage);
            switch (result)
            {
                case UserConsentVerificationResult.Verified:
                    return true;
                case UserConsentVerificationResult.DeviceNotPresent:
                    MessageBox.Show("未检测到Windows Hello设备");
                    return false;
                case UserConsentVerificationResult.NotConfiguredForUser:
                    MessageBox.Show("当前用户未设置Windows Hello");
                    return false;
                case UserConsentVerificationResult.DisabledByPolicy:
                    MessageBox.Show("Windows Hello被组策略禁用");
                    return false;
                case UserConsentVerificationResult.Canceled:
                    return false;
                default:
                    return false;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show($"验证出错:{ex.Message}");
            return false;
        }
    }
}

在WPF中调用

private async void btnHelloVerify_Click(object sender, RoutedEventArgs e)
{
    bool isAuthenticated = await WindowsHelloHelper.VerifyUserWithHelloAsync("请使用Windows Hello验证身份");
    if (isAuthenticated)
    {
        MessageBox.Show("验证成功");
        // 执行后续请求操作
    }
}

注意事项

  • 方案1支持Windows 7及以上所有版本,方案2仅支持Windows 10 1511及以上版本
  • 两种方案均由系统处理凭证,不会将密码/PIN暴露给应用,完全避免钓鱼风险
  • 若需验证用户是否为特定本地账户,方案1中可结合LogonUser API进一步确认(需管理员权限)

内容的提问来源于stack exchange,提问作者Jeronymite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:13:20