Windows 安全自定义登录验证

2024-03-16

我正在创建一个 Xaml/C# 应用程序,我希望它能够弹出登录提示。

我想知道是否可以使用 CredUIPromptForWindowsCredentials。

  • 显示 Windows 安全对话框
  • 获取输入的用户名和密码
  • 执行自定义验证
  • 如果验证成功 -> 继续应用
  • 否则如果验证失败 -> -通知用户用户名或密码无效

我已经看过了Windows 安全登录表单? https://stackoverflow.com/questions/5422140/windows-security-login-form and http://www.pinvoke.net/default.aspx/credui/creduipromptforwindowscredentials.html?diff=y http://www.pinvoke.net/default.aspx/credui/creduipromptforwindowscredentials.html?diff=y但他们没有解释如何处理验证。

我真的很喜欢一个小例子,如果用户输入用户名=“Bo”和密码=“123”,则成功,否则显示错误消息并允许用户重试。

该应用程序将安装在多台计算机上。

或者这根本不可能?

Update

受到这个问题答案的启发在 Windows Vista/7 的 C# 中显示身份验证对话框 https://stackoverflow.com/questions/4134882/show-authentication-dialog-in-c-sharp-for-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;


            }
        }
    }

应用程序.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);
        }

您可以在以下位置找到使用 CredUIPromptForWindowsCredentials 的 WPF 和 WinForms 的完整实现:Ookii 对话框 https://github.com/augustoproiete/ookii-dialogs-wpf.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows 安全自定义登录验证 的相关文章

  • EF Core 通过完全替换断开集合导航属性的更新

    使用 EF Core 5 0 我有一个 SPA 页面 可以加载Group实体及其集合Employee来自 API 的实体 var groupToUpdate await context Groups Include g gt g Emplo
  • 我如何在 C# .NET(win7 手机)中使用“DataContractJsonSerializer”读入“嵌套”Json 文件?

    我有一个问题 如果我的 json 文件看起来像这样 Numbers 45387 Words 空间桶 我可以很好地阅读它 但是如果它看起来像这样 Main Numbers 45387 Words 空间桶 某事 数字 12345 单词 克兰斯基
  • ASP.NET Web API 客户端 ProgressMessageHandler Post 任务卡在 WinForm 应用程序中

    我在用着HttpClient and ProgressMessageHandler来自MS ASP NET Web API 客户端库 http nuget org packages Microsoft AspNet WebApi Clien
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • Pip 无法在 Windows 上安装 Twisted

    我正在尝试在 Windows 8 计算机上安装 Twisted 在 Twisted 官方网站上 只有一个 Windows 版的 Wheel 文件 https twistedmatrix com trac wiki Downloads htt
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 矩阵到数组 C#

    这将是转换方阵的最有效方法 例如 1 2 3 4 5 6 7 8 9 into 1 2 3 4 5 6 7 8 9 in c 我在做 int array2D new int 1 2 3 4 5 6 7 8 9 int array1D new
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo

随机推荐

  • VSIX newtonsoft 不在包中 (VS>15.5) 抑制包

    我们有针对 vsix 项目的解决方案 直到 Visual Studio 15 4 版软件包都是使用 newtonsoft json dll 生成的 但是从该版本开始 newsoft 就被排除在软件包之外 据我所知 这是因为 Microsof
  • R / Python / Julia 中 Matlab 的类型转换函数相当于什么

    相当于Matlab的什么typecastR 中的函数 在Python中 在朱莉娅 Matlab的typecast函数的描述如下 typecast http www mathworks com help matlab ref typecast
  • 打字稿中的 GUID / UUID 类型

    我有这个功能 function getProduct id string return some product 其中 id 实际上是 GUID Typescript 没有 guid 类型 是否可以创建类型GUID手动 function g
  • 如何将 2 个部分放入 1 个段(使用 ld 脚本)

    我有以下链接器脚本 SECTIONS arora exec free space 4399531 text rodata data rel ro local arora data free space ADDR arora exec fre
  • 设置 connect-flash 中间件以供 Passport 使用

    我想访问我的护照策略在回调中指定的消息 如下所示 done null false message No such user 到目前为止我发现这些消息可以通过传递选项来显示failureFlash true进入passport authent
  • Marshmallow PermissionHelper 的 Android Robolectric 单元测试

    我想学习 Robolectric 以便将其用于 Android Marshmallow 应用程序的单元测试 我写了一个PermissionHelper使用一些方法可以使权限处理更容易一些 为了开始对该类进行单元测试 我尝试测试最简单的方法
  • 如何使用 Perl 将带有 -- 的 SQL 注释转换为 #?

    UPDATE 这就是有效的方法 fgrep ircl include sql 我有各种带有 注释的 SQL 文件 我们迁移到最新版本的 MySQL 但它讨厌这些注释 我想用 替换 我正在寻找一种递归的 就地替换的单行代码 这就是我所拥有的
  • pyparsing 和换行符

    我刚开始pyparsing我有换行问题 我的语法是 from pyparsing import newline LineEnd Literal n leaveWhitespace minus Literal plus Literal lpa
  • 将字符串解析为整数抛出 NullpointerException

    Hy 我想将字符串解析为整数 字符串类似于系列的格式 SXXEXXX 守则 应该增加情节 喜欢 S01E01 gt S01E02 另 S01E100 gt S01E101 Code String s episodes get episode
  • pip:从特定目录卸载包

    我使用以下命令将包安装到特定的本地目录中pip install t
  • Three.js 与实例 - 如果没有 FrustumCulling = false 则无法使其工作

    我正在使用 Three js 和实例化 如这个例子 https threejs org examples webgl buffergeometry instancing html 但我遇到了其他人报告的同样问题 对象被随机剪切并不断从相机中
  • 导航时片段生命周期重叠

    我有一个Activity具有多个应用程序Fragments通过使用导航组件进行切换 当我在两个片段之间切换时onCreate and onDestroy 方法似乎有重叠 因此 当片段访问相同的全局对象时 我很难编写初始化和清理片段的代码 导
  • 与杰克逊一起收集未知财产

    我正在使用 Jackson 从 JSON 创建 Java 对象 假设我有一个像这样的 JSON 字符串 a a b b c c 还有一个像这样的 pojo JsonIgnoreProperties ignoreUnknown true pu
  • 获取视图的边距

    如何从活动中获取视图的边距值 视图可以是任何类型 经过一番搜索后 我找到了填充视图的方法 但在 Margin 上找不到任何内容 有人可以帮忙吗 我尝试过这样的事情 ViewGroup LayoutParams vlp view getLay
  • slickgrid 标题的 Colspan 和 rowspan

    我只是想知道是否有一种方法可以为标题提供 colspan rowspan 并具有多个标题行 网格提供了一个辅助标题行 您可以用它来做任何您需要做的事情 检查here https github com mleibman SlickGrid w
  • 数据流中的值错误:GCS 位置无效:无

    我正在尝试从 GCS 存储桶加载数据并将内容发布到 pubsub 和 bigquery 这些是我的管道选项 options PipelineOptions project project temp location gs dataflow
  • 在 angularjs 中格式化日期和时区

    使用 angularjs 1 2 26 我无法将日期输入格式化为所需的时区 这是一个示例 http plnkr co edit CxCqoR3Awcl1NFrCZYjx p preview http plnkr co edit CxCqoR
  • 播放路由语法以忽略 slug 的一部分

    我们想要的基本上是这样的 foo controllers FooController foo 然而这不起作用 我们找到了以下解决方法 foo ignore controllers FooController foo ignore 但这使得该
  • Docker 存储库服务器向 HTTPS 客户端发出 HTTP 响应

    我使用适用于 Windows 的 Docker 工具箱 并且正在尝试参考此文档运行私有 docker 注册表https docs docker com registry deploying https docs docker com reg
  • Windows 安全自定义登录验证

    我正在创建一个 Xaml C 应用程序 我希望它能够弹出登录提示 我想知道是否可以使用 CredUIPromptForWindowsCredentials 显示 Windows 安全对话框 获取输入的用户名和密码 执行自定义验证 如果验证成