Skip to content

Commit 955d6be

Browse files
author
Çağrı Kaan Yıldırım
authored
Merge pull request #791 from MicrosoftEdge/yildirimcagri-web-authentication-requested-review-internal
CoreWebView2WebAuthenticationRequested internal API review
2 parents 5941905 + 33ac9c1 commit 955d6be

1 file changed

Lines changed: 270 additions & 0 deletions

File tree

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
<!-- USAGE
2+
* Fill in each of the sections (like Background) below
3+
* Wrap code with `single line of code` or ```code block```
4+
* Before submitting, delete all <!-- TEMPLATE marked comments in this file,
5+
and the following quote banner:
6+
-->
7+
> See comments in Markdown for how to use this spec template
8+
9+
<!-- TEMPLATE
10+
The purpose of this spec is to describe a new WebView2 feature and its APIs.
11+
12+
There are two audiences for the spec. The first are people
13+
that want to evaluate and give feedback on the API, as part of
14+
the submission process. When it's complete
15+
it will be incorporated into the public documentation at
16+
docs.microsoft.com (https://docs.microsoft.com/en-us/microsoft-edge/webview2/).
17+
Hopefully we'll be able to copy it mostly verbatim.
18+
So the second audience is everyone that reads there to learn how
19+
and why to use this API.
20+
-->
21+
22+
23+
# Background
24+
By default HTTP basic authentication and NTLM authentication requests inside WebView2 show the authentication UI, which is a dialog prompt in which the user can type in user name and password credentials just like in the Edge browser. We have been requested by WebView2 app developers to provide finer granularity for managing HTTP Basic/NTLM authentications inside WebView2, including the ability to hide the login UI and provide credentials.
25+
26+
27+
# Description
28+
We propose a new event for WebView2, CoreWebView2BasicAuthenticationRequested that will allow developers to listen on and override the HTTP Basic authentication requests in WebView2. When there is a HTTP Basic/NTLM authentication request in WebView2, the developer will have a choice to:
29+
1) Provide credentials
30+
2) Cancel the login altogether
31+
3) Ask the user for credentials via the default login prompt
32+
We also propose CoreWebView2BasicAuthenticationResponse, the runtime class that represents the app's response with credentials to the basic authentication request.
33+
34+
# Examples
35+
## Provide credentials
36+
The developer can provide the authentication credentials on behalf of the user when it encounters the Basic authentication request. In this case, the default login dialog prompt will no longer be shown to the user. If the developer provided credentials are wrong, the server may keep responding with Unauthorized, which will lead to an infinite loop so the developer should pay attention to this.
37+
38+
```cpp
39+
40+
webview2->add_BasicAuthenticationRequested(
41+
Callback<ICoreWebView2BasicAuthenticationRequestedEventHandler>(
42+
[this](
43+
ICoreWebView2* sender,
44+
ICoreWebView2BasicAuthenticationRequestedEventArgs* args)
45+
{
46+
wil::com_ptr<ICoreWebView2Environment> webviewEnvironment;
47+
m_appWindow->GetWebViewEnvironment()->QueryInterface(
48+
IID_PPV_ARGS(&webviewEnvironment));
49+
wil::com_ptr<ICoreWebView2Deferral> deferral;
50+
wil::com_ptr<ICoreWebView2BasicAuthenticationRequestedEventArgs> web_auth_args = args;
51+
args->GetDeferral(&deferral);
52+
ShowCustomLoginUI().then([web_auth_args, deferral](LPCWSTR userName, LPCWSTR password) {
53+
wil::com_ptr<ICoreWebView2BasicAuthenticationResponse> basicAuthenticationResponse;
54+
args->get_Response(&basicAuthenticationResponse);
55+
basicAuthenticationResponse->put_UserName(userName);
56+
basicAuthenticationResponse->put_Password(password);
57+
deferral->Complete();
58+
}
59+
60+
return S_OK;
61+
})
62+
.Get(),
63+
&m_BasicAuthenticationRequestedToken));
64+
```
65+
66+
```c#
67+
webView.CoreWebView2.BasicAuthenticationRequested += delegate (object sender, CoreWebView2BasicAuthenticationRequestedEventArgs args)
68+
{
69+
CoreWebView2Deferral deferral = args.GetDeferral();
70+
Credential credential = await ShowCustomLoginUIAsync();
71+
args.Response.UserName = credential.UserName;
72+
args.Response.Password = credential.Password;
73+
deferral.Complete();
74+
};
75+
```
76+
77+
## Cancel authentication prompt
78+
The developer can block the authentication request. In this case, the default login dialog prompt will no longer be shown to the user and the server will respond as if the user clicked cancel.
79+
80+
```cpp
81+
webview2->add_BasicAuthenticationRequested(
82+
Callback<ICoreWebView2BasicAuthenticationRequestedEventHandler>(
83+
[this](
84+
ICoreWebView2* sender,
85+
ICoreWebView2BasicAuthenticationRequestedEventArgs* args)
86+
{
87+
args->put_Cancel(true);
88+
89+
return S_OK;
90+
})
91+
.Get(),
92+
&m_BasicAuthenticationRequestedToken));
93+
```
94+
95+
```c#
96+
webView.CoreWebView2.BasicAuthenticationRequested += delegate (object sender, CoreWebView2BasicAuthenticationRequestedEventArgs args)
97+
{
98+
args.Cancel = true;
99+
};
100+
```
101+
102+
## Read authentication challenge string
103+
Developer can read the authentication challenge string sent by server. Note that if the developer doesn't cancel or provide a response, the default login dialog prompt will be shown to the user.
104+
105+
```cpp
106+
webview2->add_BasicAuthenticationRequested(
107+
Callback<ICoreWebView2BasicAuthenticationRequestedEventHandler>(
108+
[this](
109+
ICoreWebView2* sender,
110+
ICoreWebView2BasicAuthenticationRequestedEventArgs* args)
111+
{
112+
args->get_Challenge(&challenge);
113+
if (!ValidateChallenge(challenge.get())) { // Check the challenge string
114+
args->put_Cancel(true);
115+
}
116+
return S_OK;
117+
})
118+
.Get(),
119+
&m_BasicAuthenticationRequestedToken));
120+
```
121+
122+
```c#
123+
webView.CoreWebView2.BasicAuthenticationRequested += delegate (object sender, CoreWebView2BasicAuthenticationRequestedEventArgs args)
124+
{
125+
if (args.Challenge.Equals("Expected login credentials")) {
126+
args.Cancel = true;
127+
}
128+
};
129+
```
130+
131+
# Remarks
132+
133+
134+
# API Notes
135+
136+
137+
# API Details
138+
```idl
139+
/// WebView2 enables you to host web content using the latest Microsoft Edge
140+
/// browser and web technology.
141+
142+
[uuid(76eceacb-0462-4d94-ac83-423a6793775e), object, pointer_default(unique)]
143+
interface ICoreWebView2_4 : ICoreWebView2_3
144+
{
145+
/// ...
146+
147+
/// Add an event handler for the BasicAuthenticationRequested event.
148+
/// BasicAuthenticationRequested event is raised when WebView encounters a Basic HTTP
149+
/// Authentication request as described in
150+
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication.
151+
///
152+
/// The host can provide a response with credentials for the authentication or
153+
/// cancel the request. If the host doesn't set the Cancel property to true or
154+
/// populate the Response property, then WebView2 will show the default
155+
/// authentication challenge dialog prompt to the user.
156+
///
157+
HRESULT add_BasicAuthenticationRequested(
158+
[in] ICoreWebView2BasicAuthenticationRequestedEventHandler* eventHandler,
159+
[out] EventRegistrationToken* token);
160+
/// Remove an event handler previously added with add_WebResourceRequested.
161+
HRESULT remove_BasicAuthenticationRequested(
162+
[in] EventRegistrationToken token);
163+
}
164+
165+
/// This is the CoreWebView2BasicAuthenticationRequestedEventHandler interface
166+
[uuid(f87e5d35-3248-406b-81dd-1c36aab8081d), object, pointer_default(unique)]
167+
interface ICoreWebView2BasicAuthenticationRequestedEventHandler : IUnknown
168+
{
169+
/// Called to provide the implementer with the event args for the
170+
/// corresponding event.
171+
HRESULT Invoke(
172+
[in] ICoreWebView2* sender,
173+
[in] ICoreWebView2BasicAuthenticationRequestedEventArgs* args);
174+
}
175+
176+
/// Represents a Basic HTTP authentication response that contains a user name
177+
/// and a password as according to RFC7617 (https://tools.ietf.org/html/rfc7617)
178+
[uuid(bc9cfd60-29c4-4943-a83b-d0d2f3e7df03), object, pointer_default(unique)]
179+
interface ICoreWebView2BasicAuthenticationResponse : IUnknown
180+
{
181+
/// User name provided for authentication.
182+
[propget] HRESULT UserName([out, retval] LPWSTR* userName);
183+
/// Set user name property
184+
[propput] HRESULT UserName([in] LPCWSTR userName);
185+
186+
/// Password provided for authentication
187+
[propget] HRESULT Password([out, retval] LPWSTR* password);
188+
/// Set password property
189+
[propput] HRESULT Password([in] LPCWSTR password);
190+
}
191+
192+
/// Event args for the BasicAuthenticationRequested event. Will contain the
193+
/// request that led to the HTTP authentication challenge, the challenge
194+
/// and allows the host to provide credentials response or cancel the request.
195+
[uuid(51d3adaa-159f-4e48-ad39-a86beb2c1435), object, pointer_default(unique)]
196+
interface ICoreWebView2BasicAuthenticationRequestedEventArgs : IUnknown
197+
{
198+
/// The web resource request that led to the authentication challenge
199+
[propget] HRESULT Request([out, retval] ICoreWebView2WebResourceRequest** request);
200+
201+
/// The authentication challenge string
202+
[propget] HRESULT Challenge([out, retval] LPWSTR* challenge);
203+
204+
/// Response to the authentication request with credentials. This object will be populated by the app
205+
/// if the host would like to provide authentication credentials.
206+
[propget] HRESULT Response([out, retval] ICoreWebView2BasicAuthenticationResponse** response);
207+
208+
/// Cancel the authentication request. False by default.
209+
/// If set to true, Response set will be ignored.
210+
[propget] HRESULT Cancel([out, retval] BOOL* cancel);
211+
/// Set the Cancel property.
212+
[propput] HRESULT Cancel([in] BOOL cancel);
213+
214+
/// Returns an `ICoreWebView2Deferral` object. Use this operation to
215+
/// complete the event at a later time.
216+
HRESULT GetDeferral([out, retval] ICoreWebView2Deferral** deferral);
217+
}
218+
219+
```
220+
221+
```c#
222+
namespace Microsoft.Web.WebView2.Core
223+
{
224+
/// Event args for the BasicAuthenticationRequested event. Will contain the
225+
/// request that led to the HTTP authentication challenge, the challenge
226+
/// and allows the host to provide authentication response or cancel the request.
227+
runtimeclass CoreWebViewBasicAuthenticationRequestedEventArgs
228+
{
229+
/// The web resource request that led to the authentication challenge
230+
CoreWebView2WebResourceRequest Request { get; };
231+
232+
/// The HTTP basic authentication challenge string
233+
String Challenge { get; };
234+
235+
/// Cancel the authentication request. False by default.
236+
/// If set to true, Response will be ignored.
237+
bool Cancel { get; set; };
238+
239+
/// Response to the authentication request with credentials. This object will be populated by the app
240+
/// if the host would like to provide authentication credentials.
241+
CoreWebView2BasicAuthenticationResponse Response { get; };
242+
}
243+
244+
/// Represents a Basic HTTP authentication response that contains a user name
245+
/// and a password as according to RFC7617 (https://tools.ietf.org/html/rfc7617)
246+
runtimeclass CoreWebView2BasicAuthenticationResponse
247+
{
248+
/// User name provided for authentication.
249+
String UserName { get; set; }
250+
251+
/// Password provided for authentication
252+
String Password { get; set; };
253+
}
254+
255+
runtimeclass CoreWebView2
256+
{
257+
...
258+
259+
/// Add an event handler for the BasicAuthenticationRequested event.
260+
/// BasicAuthenticationRequested event is raised when WebView encountered a Basic HTTP
261+
/// Authentication request.
262+
///
263+
/// The host can populate the response object with credentials it wants to use for the authentication or
264+
/// cancel the request. If the host doesn't handle the event, WebView will show
265+
/// the authentication challenge dialog prompt to user.
266+
///
267+
event Windows.Foundation.TypedEventHandler<CoreWebView2, CoreWebViewBasicAuthenticationRequestedEventArgs> BasicAuthenticationRequested;
268+
}
269+
}
270+
```

0 commit comments

Comments
 (0)