news 2026/9/25 20:11:44

UWP 凭据获取实战:Windows-universal-samples 中 CredentialPicker 的三种提示场景与完整选项配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UWP 凭据获取实战:Windows-universal-samples 中 CredentialPicker 的三种提示场景与完整选项配置
  • 示例工程

【免费下载链接】Windows-universal-samples

API samples for the Universal Windows Platform.

项目地址:https://gitcode.com/gh_mirrors/wi/Windows-universal-samples
点击查看免费下载

本文基于 Windows-universal-samples 仓库中的 CredentialPicker 示例(归档于 archived/CredentialPicker),系统讲解如何通过Windows.Security.Credentials.UI.CredentialPicker类在 UWP 应用中弹出系统级凭据提示框并获取用户名、密码、域信息。示例覆盖三种由简到繁的调用形态:纯消息提示、消息加标题提示、以及可自定义认证协议、保存复选框与显示行为的完整选项模式;读完本文你将掌握pickAsync的全部重载方式、CredentialPickerOptions各字段的取值语义,以及如何将取回的凭据用于后续需要认证的 API(如 HttpClient),为单点登录(SSO)场景提供支撑。

示例定位:为需要凭据的 API 提供 SSO 支撑

本示例演示的核心能力非常聚焦:使用Windows.Security.Credentials.UI.CredentialPicker类检索用户凭据,并将其传递给可能需要凭据的 API(例如 HttpClient)。它的典型价值在于支持单点登录(SSO)——用户在一次凭据输入后,应用可以将凭据复用于多个需要认证的服务调用。

从仓库的归档结构看,该示例目前保留了 JavaScript(WinJS)实现,核心代码位于 archived/CredentialPicker/js/js/ 下,配套页面位于 archived/CredentialPicker/js/html/。示例允许用户启动不同类型的凭据提示,共提供三种可选场景:

  • Message:仅带提示消息的基础凭据对话框;
  • Message and Caption:提示消息外加窗口标题(Caption)的对话框;
  • Message, Caption, Save Credential Option, and a type of protocol:消息、标题、凭据保存复选框状态以及认证协议类型全部可配置的完整模式。

这三种场景在 sample-configuration.js 中注册为SdkSample.scenarios,分别对应scenario1.js、scenario2.js、scenario3.js三个页面脚本,运行时可从应用导航栏依次切换体验。

运行环境与工程配置

原文档明确要求操作系统为Windows 10。从 Package.appxmanifest 可以看出,工程面向Windows.Universal设备家族,MinVersion为10.0.10240.0、MaxVersionTested为10.0.18362.0,即覆盖 Windows 10 初版至今的通用设备范围。

值得注意的是,该清单的<Capabilities>节点为空,说明弹出 CredentialPicker 对话框本身不需要声明任何特殊系统功能(capability),这是凭据获取类 API 的典型特征——UI 由系统托管,应用只负责传参与接收结果。

示例以default.html为启动页,应用标识为Microsoft.SDKSamples.CredentialPicker.JS。工程文件 CredentialPicker.jsproj 与解决方案 CredentialPicker.sln 位于同一目录,可直接用 Visual Studio 打开构建。

构建示例

原文档给出的构建流程如下(适用于本仓库的完整下载解压场景):

  1. 若通过 ZIP 下载示例集合,请务必解压整个归档,而不仅是包含目标示例的单个文件夹,因为示例共享同一套依赖;
  2. 启动 Microsoft Visual Studio 2017,选择File>Open>Project/Solution;
  3. 在解压后的目录中进入Samples子文件夹,再进入本示例对应的子文件夹,最后进入所选语言(C++、C# 或 JavaScript)的子文件夹,双击其中的 Visual Studio 解决方案(.sln)文件;
  4. 按 Ctrl+Shift+B,或选择Build>Build Solution完成构建。

说明:本仓库归档目录 archived/CredentialPicker 目前仅保留 JavaScript 实现,构建时请使用js子目录下的CredentialPicker.sln。示例其余语言版本的对应代码可参考仓库中其他采用同主题 API 的示例目录。

运行示例

运行分为两种情况:

仅部署(Deploy):选择Build>Deploy Solution。

部署并运行:

  • 调试运行:按 F5 或选择Debug>Start Debugging;
  • 免调试运行:按 Ctrl+F5 或选择Debug>Start Without Debugging。

运行后,应用首页会列出三个场景(Message、Message + Caption、Credential Picker Options),点击任一场景的 Launch 按钮即可弹出对应的系统凭据对话框。

场景一:最简调用 pickAsync(targetName, message)

场景一展示pickAsync的两参数重载。页面 scenario1.html 提供“Message”与“Target”两个输入框(默认值分别为 "Enter your credentials" 与 "contoso.com"),点击 Launch 后执行 scenario1.js 中的核心逻辑:

Windows.Security.Credentials.UI.CredentialPicker.pickAsync(targetName, message).then(function (results) { document.getElementById("OutputDomainName").value = results.credentialDomainName; document.getElementById("OutputUserName").value = results.credentialUserName; document.getElementById("OutputPassword").value = results.credentialPassword; document.getElementById("OutputCredentialSaved").value = results.credentialSaved ? "Yes" : "No"; document.getElementById("OutputCredentialSaveState").value = (results.credentialSaveOption === Windows.Security.Credentials.UI.CredentialSaveOption.hidden) ? "Hidden" : ((results.credentialSaveOption === Windows.Security.Credentials.UI.CredentialSaveOption.selected) ? "Selected" : "Unselected"); WinJS.log && WinJS.log("pickAsync status: " + results.errorCode, "sample", "status"); });

要点:

  • targetName是目标服务名(示例中即 "contoso.com" 一类的资源标识),会显示在对话框中并随凭据一并返回;
  • message是展示给用户的提示文本;
  • 整个调用包在try/catch中,同步异常(如参数非法)会通过WinJS.log输出错误信息;
  • 两参数重载下,对话框不会提供"记住凭据"复选框(保存选项被隐藏)。

场景二:三参数重载 pickAsync(targetName, message, caption)

场景二在场景一基础上增加caption参数,用于设置对话框窗口的标题栏文本。页面 scenario2.html 多了一个 "Caption" 输入框(默认值 "WindowCaption"),核心调用见 scenario2.js:

Windows.Security.Credentials.UI.CredentialPicker.pickAsync(targetName, message, caption).then(function (results) { // 结果处理与场景一相同: // results.credentialDomainName / credentialUserName / credentialPassword // results.credentialSaved / credentialSaveOption / errorCode });

两参数与三参数重载的区别仅在于是否指定窗口标题:若不传caption,系统使用默认标题;传入后对话框标题与提示消息同时可控,适合需要向用户交代"为哪个服务输入凭据"的场合。

场景三:使用 CredentialPickerOptions 的完整配置

场景三是能力最完整的形态:不再使用简化重载,而是构造Windows.Security.Credentials.UI.CredentialPickerOptions实例,逐一配置后调用pickAsync(options)。对应页面 scenario3.html 提供了消息、标题、目标、认证协议、自定义协议、保存复选框状态、是否始终显示对话框、是否由调用方保存凭据共八个输入项,核心逻辑位于 scenario3.js:

var options = new Windows.Security.Credentials.UI.CredentialPickerOptions(); options.message = document.getElementById("InputMessage").value; options.caption = document.getElementById("InputCaption").value; options.targetName = document.getElementById("InputTarget").value; options.alwaysDisplayDialog = document.getElementById("InputAlwaysShowUI").checked; options.callerSavesCredential = document.getElementById("InputCallerSaves").checked; // 认证协议选择 switch (document.getElementById("InputProtocol").value) { case "Negotiate": options.authenticationProtocol = Windows.Security.Credentials.UI.AuthenticationProtocol.negotiate; break; case "Kerberos": options.authenticationProtocol = Windows.Security.Credentials.UI.AuthenticationProtocol.kerberos; break; case "CredSsp": options.authenticationProtocol = Windows.Security.Credentials.UI.AuthenticationProtocol.credSsp; break; case "Basic": options.authenticationProtocol = Windows.Security.Credentials.UI.AuthenticationProtocol.basic; break; case "Digest": options.authenticationProtocol = Windows.Security.Credentials.UI.AuthenticationProtocol.digest; break; case "NTLM": options.authenticationProtocol = Windows.Security.Credentials.UI.AuthenticationProtocol.ntlm; break; case "Custom": options.authenticationProtocol = Windows.Security.Credentials.UI.AuthenticationProtocol.custom; options.customAuthenticationProtocol = document.getElementById("InputCustomProtocol").value; break; default: WinJS.log && WinJS.log("Bad auth protocol specified: " + document.getElementById("InputProtocol").value, "sample", "error"); break; } // 保存复选框状态 switch (document.getElementById("InputCheckboxState").value) { case "Unselected": options.credentialSaveOption = Windows.Security.Credentials.UI.CredentialSaveOption.unselected; break; case "Selected": options.credentialSaveOption = Windows.Security.Credentials.UI.CredentialSaveOption.selected; break; case "Hidden": options.credentialSaveOption = Windows.Security.Credentials.UI.CredentialSaveOption.hidden; break; default: WinJS.log && WinJS.log("Bad save option specified: " + document.getElementById("InputCheckboxState").value, "sample", "error"); break; } Windows.Security.Credentials.UI.CredentialPicker.pickAsync(options).then(function (results) { // 结果处理同上,见场景一代码块 });

CredentialPickerOptions 字段一览

字段类型语义与取值
messageString对话框提示消息(示例默认 "Enter your credentials")
captionString对话框标题(示例默认 "WindowCaption")
targetNameString目标服务名,用于标识凭据归属(示例默认 "contoso.com")
authenticationProtocol枚举认证协议,取值见下表
customAuthenticationProtocolString仅当协议为custom时生效,指定自定义协议名称
credentialSaveOption枚举"保存凭据"复选框的显示与勾选状态
alwaysDisplayDialogBoolean为true时即使系统缓存中有可用凭据也强制弹出对话框
callerSavesCredentialBoolean为true时由调用方负责保存凭据(API 不再提示保存)

认证协议枚举(AuthenticationProtocol)

从 scenario3.js 的 switch 分支可确认支持的协议,与 UI 下拉框 scenario3.html 中的选项一一对应:

  • negotiate(Negotiate,默认综合协商)
  • kerberos(Kerberos)
  • credSsp(CredSSP,凭据安全支持提供程序)
  • basic(Basic,基本认证)
  • digest(Digest,摘要认证)
  • ntlm(NTLM)
  • custom(Custom,配合customAuthenticationProtocol指定具体协议字符串)

保存复选框状态(CredentialSaveOption)

  • unselected:显示复选框但默认不勾选;
  • selected:显示复选框且默认勾选;
  • hidden:隐藏复选框(此时对话框中不出现保存选项)。

结果对象:pickAsync 返回了什么

三个场景共用同一套结果字段处理逻辑,完整字段包括:

字段类型说明
credentialDomainNameString用户输入的域/域名部分
credentialUserNameString用户名
credentialPasswordString密码(示例中直接回显到页面用于演示;生产环境应避免明文展示)
credentialSavedBoolean凭据是否已被保存(页面显示 "Yes"/"No")
credentialSaveOption枚举用户最终选择的保存选项状态,映射为 Hidden / Selected / Unselected 展示
errorCode数值异步操作状态码,示例通过WinJS.log输出以便排查

得到凭据后,即可将其用于需要认证的 API(如 HttpClient 的请求头构造),实现"一次输入、多处复用"的 SSO 体验。

源码结构速览

  • scenario1.js:两参数重载演示;
  • scenario2.js:三参数重载演示;
  • scenario3.js:CredentialPickerOptions完整配置演示;
  • sample-configuration.js:注册示例标题与三个场景的导航元数据;
  • scenario1.html、scenario2.html、scenario3.html:三个场景的输入/输出 UI;
  • Package.appxmanifest:应用清单,无特殊 capability 声明;
  • CredentialPicker.sln / CredentialPicker.jsproj:解决方案与工程文件。

使用建议与注意事项

  • 优先使用选项式调用:当需要控制认证协议、保存行为或强制显示对话框时,务必使用pickAsync(options)而非简化重载;涉及 SSO 多服务复用时,alwaysDisplayDialog = false配合系统凭据缓存可减少重复输入。
  • 凭据安全:示例将credentialPassword明文写入页面仅供演示;真实应用应尽快使用后销毁,避免日志与 UI 中残留明文密码。
  • 协议选择要与目标服务匹配:Negotiate/Kerberos/NTLM 面向域环境,Basic/Digest 面向 HTTP 基础认证场景,CredSSP 多用于远程桌面类认证,Custom 则用于私有认证方案。
  • 无 capability 负担:如本示例清单所示,调用 CredentialPicker 无需在 Package.appxmanifest 中声明额外权限,集成成本低。
  • 示例工程

【免费下载链接】Windows-universal-samples

API samples for the Universal Windows Platform.

项目地址:https://gitcode.com/gh_mirrors/wi/Windows-universal-samples
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 20:10:01

知识图谱也会有脏数据?用 pySHACL 给 RDF 加一道数据校验

做 MySQL 的时候&#xff0c;我们对“数据校验”其实很熟悉。 比如用户表&#xff1a; CREATE TABLE user (id BIGINT PRIMARY KEY,username VARCHAR(64) NOT NULL,age INT );这里已经偷偷规定了很多规则&#xff1a; id 必须有 username 不能为空 username 最长 64 age 必须是…

作者头像 李华
网站建设 2026/9/25 20:07:36

堆排序图解:厘清算法堆与内存堆的区别

1. 为什么堆排序总被说“难懂”&#xff1f;先拆掉那个“堆”的心理门槛很多人第一次看到“堆排序”三个字&#xff0c;脑子里立刻浮现出编译器报错里那行刺眼的“java.lang.OutOfMemoryError: Java heap space”&#xff0c;或者调试时在IDE里点开“Variables”面板却找不到某…

作者头像 李华
网站建设 2026/9/25 20:07:34

剪贴板工作原理与复制粘贴失效排查全指南

复制粘贴这事儿&#xff0c;看着简单&#xff0c;翻车的时候能把人逼疯。Excel里明明选中了就是粘贴不了&#xff0c;Ubuntu虚拟机里从Windows复制文本过来变成乱码&#xff0c;Illustrator里复制了半天没反应&#xff0c;Jupyter里键盘都快按烂了代码还是过不来。这些场景我全…

作者头像 李华
网站建设 2026/9/25 20:05:39

运维日常用什么远程工具?工具链收敛实战

做 IT 支持和运维的&#xff0c;大概率都有过这种经历&#xff1a;电脑里装了四五个远程相关的工具&#xff0c;远控一个、传文件一个、内网穿透又一个&#xff0c;账号分别登&#xff0c;连接分别配&#xff0c;出门在外还要想半天"我现在该开哪个"。 这篇聊聊我怎么…

作者头像 李华
网站建设 2026/9/25 20:05:28

运维2-电商业务

1.MySQL 主从配置主从复制的原理 &#xff1a;主服务器开启bin-log&#xff08;记录了写操作&#xff09; 从服务器获取到主服务器的bin-log 记录到relay-log中。从服务器在通过异步的线程方式&#xff0c;对于relay-log进行重放操作。 IO线程去主服务器binlog日志拷贝 > 写…

作者头像 李华