Basic authentication for WebView2 apps
Basic authentication is an authentication approach that's part of the HTTP protocol.
Basic authentication for WebView2 apps includes a sequence of authentication and navigation steps to retrieve a webpage from an HTTP server. The WebView2 control acts as an intermediary for communication between the host app and the HTTP server.
Use HTTPS for sending credentials
Warning: You must use HTTPS when using Basic Authentication. Otherwise the username and password are not encrypted. You may want to consider other forms of authentication.
The HTTP standard for basic authentication includes the authentication credentials (username and password) unencrypted. Therefore, you must use https
, to ensure that the credentials are encrypted.
The order of navigation events
The basic authentication event happens in the middle of the sequence of events:
NavigationStarting
- navigation eventContentLoading
- navigation eventBasicAuthenticationRequested
DOMContentLoaded
NavigationCompleted
- navigation event
For more information, see Navigation events for WebView2 apps.
Communication between the HTTP server, WebView2 control, and host app
The HTTP server checks authentication (username and password credentials) and returns either an error document or the requested webpage.
The WebView2 control instance raises the events. The WebView2 control sits between the HTTP server and the host app. The WebView2 control serves as an intermediary for communication between the host app and the HTTP server.
You write the host app. The host app sets the user name and password on the event's arguments (
EventArgs
) response objects.
BasicAuthenticationRequestedEventArgs
has a Response
property. The Response
property is an object that contains the username and password properties.
Sequence of navigation events
The following diagram shows the flow of navigation events for basic authentication for WebView2 apps:
The host app tells the WebView2 control to navigate to a URI.
The WebView2 control talks to the HTTP server requesting to get the document at a specified URI.
The HTTP server replies to the WebView2 control, saying "You can't get that URI (document) without authentication."
The WebView2 control tells the host app "Authentication is needed" (which is the
BasicAuthenticationRequested
event).The host app responds to that event by providing the username and password to the WebView2 control.
The WebView2 control again requests the URI from the HTTP server, but this time with the authentication (username and password).
The HTTP server evaluates the credentials (username and password).
The HTTP server might deny the credentials and request new credentials.
The HTTP server might reject the username and password; it might tell the WebView2 control "You're not permitted to get that URI/document".
The WebView2 control renders the error page that's returned by the HTTP server. The rendering occurs between the
ContentLoading
event andDOMContentLoaded
event.The HTTP server might accept the authentication credentials and return the requested document.
The WebView2 control renders the returned document. The rendering occurs between the
ContentLoading
event andDOMContentLoaded
event.
Example code: App providing credentials that are known ahead of time
The following simplified example shows the host app providing credentials (user name and password) that are known ahead of time. This example is a slightly modified version of the code that's in WebView2Samples repo > WebView2APISample > ScenarioAuthentication.cpp.
This example isn't realistic, because:
- In practice, you'd prompt the user for the username and password rather than hardcoding them like
"user"
and"pass"
. - This code is synchronous, but you'd probably use asynchronous code instead.
For more realistic code, see the subsequent section.
// Prerequisite: Before using this code, make sure you read the section "Use HTTPS
// for sending credentials" in this article.
webView.CoreWebView2.BasicAuthenticationRequested += delegate (
object sender,
CoreWebView2BasicAuthenticationRequestedEventArgs args)
{
args.Response.UserName = "user";
args.Response.Password = "pass";
};
APIs:
Example code: Prompting user for credentials
This example demonstrates a host app prompting the user for credentials (user name and password), and uses async code.
This example builds upon the above sample, by adding the following features:
- Displays a dialog to prompt the user for their username and password.
- Calls the
GetDeferral
method on theevent
argument.
// Prerequisite: Before using this code, make sure you read the section "Use HTTPS
// for sending credentials" in this article.
webView.CoreWebView2.BasicAuthenticationRequested += delegate (
object sender,
CoreWebView2BasicAuthenticationRequestedEventArgs args)
{
// We need to show UI asynchronously so we obtain a deferral.
// A deferral will delay the CoreWebView2 from
// examining the properties we set on the event args until
// after we call the Complete method asynchronously later.
// This gives us time to asynchronously show UI.
CoreWebView2Deferral deferral = args.GetDeferral();
// We avoid potential reentrancy from running a message loop in the
// event handler by showing our download dialog later when we
// complete the deferral asynchronously.
System.Threading.SynchronizationContext.Current.Post((_) =>
{
using (deferral)
{
// When prompting the end user for authentication its important
// to show them the URI or origin of the URI that is requesting
// authentication so the end user will know who they are giving
// their username and password to.
// Its also important to display the challenge to the end user
// as it may have important site specific information for the
// end user to provide the correct username and password.
// Use an app or UI framework method to get input from the end user.
TextInputDialog dialog = new TextInputDialog(
title: "Authentication Request",
description: "Authentication request from " + args.Uri + "\r\n" +
"Challenge: " + args.Challenge,
defaultInput: "username\r\npassword");
bool userNameAndPasswordSet = false;
if (dialog.ShowDialog().GetValueOrDefault(false))
{
string[] userNameAndPassword = dialog.Input.Text.Split(
new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
if (userNameAndPassword.Length > 1)
{
args.Response.UserName = userNameAndPassword[0];
args.Response.Password = userNameAndPassword[1];
userNameAndPasswordSet = true;
}
}
// If we didn't get a username and password from the end user then
// we cancel the authentication request and don't provide any
// authentication.
if (!userNameAndPasswordSet)
{
args.Cancel = true;
}
}
}, null);
};
APIs:
- CoreWebView2BasicAuthenticationRequestedEventArgs Class
- Properties:
Cancel
Challenge
Response
Uri
- Methods:
GetDeferral()
- Properties:
How navigations work
This section provides optional background information about how navigations work.
A navigation corresponds to multiple navigation events. By navigation, we here mean each retry, starting with the NavigationStarting
box of the above diagram, through the NavigationCompleted
box.
When a new navigation begins, a new navigation ID is assigned. For the new navigation, the HTTP server gave the WebView2 control a document. This is the "have document" navigation.
As a part of navigation, the WebView2 control renders the corresponding page (the requested page or an error page, whichever is returned by the HTTP server), and a "success" or "failure" outcome raises a successful or failed NavigationCompleted
event.
For more information, see Navigation events for WebView2 apps.
Navigations for basic authentication
There are two kinds of navigations in the flow:
- A "server requested authentication" navigation.
- A "server gave the WebView2 control a document" navigation.
After the first type of navigation, the server has asked for authentication and the app needs to try that kind of navigation again (with a new navigation ID). The new navigation will use whatever the host app gets from the events arguments response objects.
An HTTP server may require HTTP authentication. In this case, there's a first navigation, which has the navigation events that are listed above. The HTTP server returns a 401 or 407 HTTP response, and so the NavigationCompleted
event has a corresponding failure. The WebView2 then renders a blank page, and raise the BasicAuthenticationRequested
event, which will potentially prompt the user for credentials.
If the BasicAuthenticationRequested
event is canceled, then there's no subsequent navigation and the WebView2 will remain to display the blank page.
If the BasicAuthenticationRequested
event isn't canceled, the WebView2 will perform the initial navigation again, but this time, using any provided credentials. You'll again see all the same navigation events as before.
If the credentials aren't accepted by the HTTP server, navigation fails again with 401 or 407. In that case, the CoreWebView2
class instance again raises the BasicAuthenticationRequested
event, and navigation continues as above.
The navigation succeeds if the credentials are accepted by the HTTP server. The navigation fails if the HTTP server denies authentication (the server typically returns an error page).
The navigations before and after the BasicAuthenticationRequested
event are distinct navigations and have distinct navigation IDs.
Navigation event args
has a property: the NavigationId
. The NavigationId
ties together navigation events that correspond to a single navigation. The NavigationId
remains the same during each navigation, such as a retry. During the next pass through the event flow, a different NavigationId
is used.
API Reference overview
See also
- HTTP authentication at MDN.