.NET混合开发解决方案14 WebView2的基本身份验证
WebView2控件应用详解系列博客
WebView2 应用的基本身份验证包括从 HTTP 服务器检索网页的一系列身份验证和导航步骤。 WebView2 控件充当主机应用和 HTTP 服务器之间通信的中介。
导航事件的顺序友情提醒:使用基本身份验证时必须使用 HTTPS。 否则,用户名和密码不加密。 您可能需要考虑其他形式的身份验证。 基本身份验证的 HTTP 标准包括未加密 (用户名和密码) 凭据。 因此,必须使用 HTTPS以确保凭据已加密。
基本身份验证事件在事件序列的中间发生:
NavigationStarting
- 导航事件ContentLoading
- 导航事件BasicAuthenticationRequested
DOMContentLoaded
NavigationCompleted
- 导航事件
-
HTTP 服务器检查身份验证 (用户名和密码凭据) 并返回错误文档或请求的网页。
-
WebView2 控件实例引发事件。 WebView2 控件位于 HTTP 服务器和主机应用之间。 WebView2 控件充当主机应用和 HTTP 服务器之间通信的中介。
-
编写主机应用。 主机应用在响应对象中设置事件参数 ()
EventArgs
密码。
BasicAuthenticationRequestedEventArgs
具有 属性 Response
。 属性 Response
是包含用户名和密码属性的对象。
下图显示了 WebView2 应用的基本身份验证的导航事件流:
-
主机应用指示 WebView2 控件导航到 URI。
-
WebView2 控件与 HTTP 服务器通信,请求获取位于指定 URI 的文档。
-
HTTP 服务器答复 WebView2 控件,指出"未经身份验证 (无法获取) URI"。
-
WebView2 控件指示主机应用"需要身份验证" (
BasicAuthenticationRequested事件
) 。 -
主机应用通过向 WebView2 控件提供用户名和密码来响应该事件。
-
WebView2 控件再次从 HTTP 服务器请求 URI,但这次使用的是身份验证 (用户名和密码) 。
-
HTTP 服务器对用户名和密码 (凭据) 进行评估。
-
HTTP 服务器可能会拒绝凭据并请求新的凭据。
-
HTTP 服务器可能会拒绝用户名和密码;它可能会告诉 WebView2 控件"不允许获取该 URI/文档"。
-
WebView2 控件呈现 HTTP 服务器返回的错误页。 呈现发生在
ContentLoading
事件和DOMContentLoaded
事件之间。 -
HTTP 服务器可能会接受身份验证凭据并返回请求的文档。
-
WebView2 控件呈现返回的文档。 呈现发生在
ContentLoading
事件和DOMContentLoaded
事件之间。
示例程序
BasicAuthenticationRequeste事件中实现具体的校验凭证逻辑
1 private void CoreWebView2_BasicAuthenticationRequested(object? sender, CoreWebView2BasicAuthenticationRequestedEventArgs args) 2 { 3 /* 开发者需要异步显示UI,以便获得 CoreWebView2Deferral 对象。 4 * 该对象将延迟 CoreWebView2 检查开发者在事件参数上设置的属性,直到稍后异步调用 Complete 方法。 5 * 这给了开发者异步显示UI的时间。 6 */ 7 CoreWebView2Deferral deferral = args.GetDeferral(); 8 9 // 通过在异步完成延迟后显示下载对话框,我们避免了在事件处理程序中运行消息循环的潜在可重入性 10 System.Threading.SynchronizationContext.Current.Post((_) => 11 { 12 using (deferral) 13 { 14 // 提示最终用户进行身份验证时,重要的是向他们显示请求身份验证的URI或URI的来源,以便最终用户知道他们将用户名和密码提供给谁。 15 16 // 向最终用户显示挑战也很重要,因为它可能会为最终用户提供重要的站点特定信息,以提供正确的用户名和密码 17 18 // 使用应用程序或UI框架方法从最终用户获取输入。 19 20 bool userNameAndPasswordSet = false; 21 Frm6Auth frm = new Frm6Auth(args.Uri); 22 DialogResult dialogResult = frm.ShowDialog(); 23 if (dialogResult == DialogResult.OK) 24 { 25 args.Response.UserName = frm.UserName; 26 args.Response.Password = frm.UserPwd; 27 userNameAndPasswordSet = true; 28 } 29 30 /* TODO 此处要做真正的认证校验。测试程序只做举例说明 */ 31 if (args.Response.UserName != "admin" && args.Response.Password != "admin123456") 32 { 33 MessageBox.Show("用户名与密码不正确。", "提示", 34 MessageBoxButtons.RetryCancel, 35 MessageBoxIcon.Warning); 36 37 userNameAndPasswordSet = false; 38 } 39 40 // 如果我们没有从最终用户那里获得用户名和密码。我们取消认证请求,不提供任何认证 41 if (!userNameAndPasswordSet) 42 { 43 args.Cancel = true; 44 } 45 } 46 }, null); 47 }
Frm6Auth窗体如下
基本身份验证的导航
有两种类型的导航:
- "服务器请求的身份验证"导航。
- "服务器为 WebView2 控件提供文档"导航。
第一种类型的导航后,服务器要求进行身份验证,并且应用需要再次尝试这种导航 (使用新的导航 ID) 。 新导航将使用主机应用从事件参数响应对象获取的任何内容。
HTTP 服务器可能需要 HTTP 身份验证。 在这种情况下,存在第一 个导航,该导航具有上面列出的导航事件。 HTTP 服务器返回 401 或 407 HTTP 响应 NavigationCompleted
,因此事件具有相应的失败。 然后,WebView2 呈现空白页 BasicAuthenticationRequested
并引发事件,这可能会提示用户输入凭据。
BasicAuthenticationRequested
如果取消该事件,则没有后续导航,并且 WebView2 将保留以显示空白页。BasicAuthenticationRequested
如果未取消该事件,WebView2 将再次执行初始导航,但这次使用任何提供的凭据。 你将再次看到与之前相同的导航事件。
如果 HTTP 服务器不接受凭据,导航将再次因 401 或 407 失败。 在这种情况下,类 CoreWebView2
实例将再次引发 BasicAuthenticationRequested
事件,并且导航将继续,如上所述。
如果 HTTP 服务器接受凭据,则导航成功。 如果 HTTP 服务器拒绝身份验证,则 (通常返回错误页) 。
事件之前和之后导航 BasicAuthenticationRequested
是不同的导航,并且具有不同的导航 ID。导航event args
有一个属性:NavigationId
与 NavigationId
单个导航对应的导航事件紧密结合。 在每个 NavigationId
导航过程中保持不变,如重试。 在下次传递事件流期间,使用不同的 NavigationId
方法。