Event flow after webRequest.onAuthRequired does not match documention and is not interoperable with Chrome
Categories
(WebExtensions :: Request Handling, task, P3)
Tracking
(Not tracked)
People
(Reporter: robwu, Unassigned)
References
Details
Attachments
(1 file)
1.99 KB,
application/zip
|
Details |
The behavior of the webRequest.onAuthRequired
event in relation with other webRequest is currently underspecified, and the only documented flow of events does not match the actual implementation. Moreover, Firefox's behavior differs from Chrome's (Safari doesn't support webRequest). This issue describes the current behavior and highlights the mismatch with the documentation. The purpose of this ticket is to define the desired behavior, and make sure that the implementation and documentation reflect this. To help with getting there, here is a description of the status quo:
MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest
- ... and specifically the event transition diagram (link to line in source of MDN)
- MDN claims that onAuthRequired can result in onResponseStarted or onBeforeSendHeaders.
- This diagram is likely derived from the same diagram as Chrome's docs: https://developer.chrome.com/docs/extensions/reference/webRequest/#life-cycle-of-requests (webarchive copy, source code of Chrome's docs)
- No implementation ever resumed from onBeforeSendHeaders. A restarted request has always continued at onBeforeRequest (exceptions in the past - bug 1494033 and crbug.com/809761)
- MDN does not mention anything about requestId in the main article.
requestId
is listed in the reference of individual requests, e.g. onBeforeRequest details.requestId. - Neither MDN nor Chrome's doc mention anything about the re-use of
requestId
when a request is restarted. The diagram shows that a request can "restart" after onBeforeRedirect and onAuthRequired.
Chrome (115):
- In Chrome, when onAuthRequired is fired:
- While
onAuthRequired
is blocking the request (asyncBlocking):- The UI where users can input credentials is not shown yet.
- When all
onAuthRequired
listeners (if any) have responded:- The onResponseStarted + onCompleted event fire, with
details.statusCode = 401
/407
. This always happens, regardless of the user/extension's response to the auth request. - The UI prompt for credentials is shown to the user if needed.
- The onResponseStarted + onCompleted event fire, with
- While
- When auth credentials are provided (by the user or extension), the request restarts at onBeforeRequest as usual, with a new
requestId
.- There is no obvious way to relate
requestId
to the previous request.
- There is no obvious way to relate
- Chrome's documentation claims that every request ends in onCompleted or onErrorOccurred. Indeed, when a request is restarted one of these are fired for the original
requestId
:- Restarted after onAuthRequired: no more events are fired (onResponseStarted + onCompleted have already fired before).
- Restarted after onBeforeRedirect: onErrorOccurred is fired.
Firefox (release 116, Nightly 118.0a1):
- In Firefox, when onAuthRequired is fired:
- While
onAuthRequired
is blocking the request ("blocking" + listener returns Promise):- The UI where users can input credentials is not shown yet.
- When all
onAuthRequired
listeners (if any) have responded:- The onResponseStarted + onCompleted event do not fire. No events are emitted at all.
- The UI prompt for credentials is shown to the user if needed.
- While
- When auth credentials are provided (by the user or extension), the request restarts at onBeforeRequest as usual, with the same requestId.
- The re-use of requestId is not documented on MDN.
- Only when auth credentials are not provided: onResponseStarted + onCompleted are fired, with
details.statusCode = 401
/407
. - Because Firefox re-uses the same
requestId
upon restarting the request, onAuthRequired is followed byonBeforeRequest
.- To re-iterate: this event transition is not documented on MDN.
- The flow is similar to onBeforeRedirect -> onBeforeRequest (but this transition is documented on MDN).
The highlighted fragments highlight the differences in comparison with Chrome.
Reporter | ||
Comment 1•11 months ago
|
||
Test extension to log events. Although the extension does not rely on it, the zip file also includes a Node.js server to simulate HTTP Basic Auth and Basic Proxy Authentication as a reference.
STR:
- Load the extension (at
about:debugging
in Firefox, orchrome://extensions/
in Chrome).
- The extension will print every webRequest event.
- Inspect the background page (in Chrome, the Developer Mode checkbox needs to be enabled first).
- Allow the extension access to Private Browsing mode (via the extension card in
about:addons
in Firefox, via a checkbox atchrome://extensions/
in Chrome). - Open a private browsing window.
- Click on the extension button, which opens https://httpbingo.org/basic-auth/user/passwd
- This test page triggers HTTP Basic Auth (the expected credentials are "user" and "passwd").
- The extension does not provide credentials itself, but delays the event by 2 seconds.
- View the console from step 1 to inspect the events.
- To test again, close the private browsing window (which will clear the auth cache) and restart from step 4.
Reporter | ||
Comment 2•11 months ago
|
||
Examples:
When bad credentials are provided in Chrome 115:
requestId 675 onBeforeRequest main_frame https://httpbingo.org/basic-auth/user/passwd 0
requestId 675 onBeforeSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 1
requestId 675 onSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 2
requestId 675 onHeadersReceived main_frame https://httpbingo.org/basic-auth/user/passwd 3
requestId 675 onAuthRequired main_frame https://httpbingo.org/basic-auth/user/passwd 4
requestId 675 auth suspended
requestId 675 auth resumed
requestId 675 onResponseStarted main_frame https://httpbingo.org/basic-auth/user/passwd 5
requestId 675 onCompleted main_frame https://httpbingo.org/basic-auth/user/passwd 6
(auth UI showed up: user cancels without providing credentials)
requestId 676 onBeforeRequest main_frame https://httpbingo.org/basic-auth/user/passwd 7
requestId 676 onBeforeSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 8
requestId 676 onSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 9
requestId 676 onHeadersReceived main_frame https://httpbingo.org/basic-auth/user/passwd 10
requestId 676 onAuthRequired main_frame https://httpbingo.org/basic-auth/user/passwd 11
requestId 676 auth suspended
requestId 676 auth resumed
requestId 676 onResponseStarted main_frame https://httpbingo.org/basic-auth/user/passwd 12
requestId 676 onCompleted main_frame https://httpbingo.org/basic-auth/user/passwd 13
(the page shows authorized:false
)
When the correct credentials are provided in Chrome, the post-authentication event transition looks like this instead of the above:
(auth UI showed up: user cancels without providing credentials)
requestId 676 onBeforeRequest main_frame https://httpbingo.org/basic-auth/user/passwd 7
requestId 676 onBeforeSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 8
requestId 676 onSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 9
requestId 676 onHeadersReceived main_frame https://httpbingo.org/basic-auth/user/passwd 10
requestId 676 onResponseStarted main_frame https://httpbingo.org/basic-auth/user/passwd 11
requestId 676 onCompleted main_frame https://httpbingo.org/basic-auth/user/passwd 12
(the page shows authorized:true
)
When bad credentials are provided in Firefox 117:
requestId 518 onBeforeRequest main_frame https://httpbingo.org/basic-auth/user/passwd 0
requestId 518 onBeforeSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 1
requestId 518 onSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 2
requestId 518 onHeadersReceived main_frame https://httpbingo.org/basic-auth/user/passwd 3
requestId 518 onAuthRequired main_frame https://httpbingo.org/basic-auth/user/passwd 4
requestId 518 auth suspended
requestId 518 auth resumed
(auth UI showed up: user cancels without providing credentials)
requestId 518 onResponseStarted main_frame https://httpbingo.org/basic-auth/user/passwd 5
requestId 518 onCompleted main_frame https://httpbingo.org/basic-auth/user/passwd 6
When the correct credentials are provided in Firefox, the post-authentication event transition looks like this instead of the above:
(auth UI showed up: user cancels without providing credentials)
requestId 518 onBeforeRequest main_frame https://httpbingo.org/basic-auth/user/passwd 5
requestId 518 onBeforeSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 6
requestId 518 onSendHeaders main_frame https://httpbingo.org/basic-auth/user/passwd 7
requestId 518 onHeadersReceived main_frame https://httpbingo.org/basic-auth/user/passwd 8
requestId 518 onResponseStarted main_frame https://httpbingo.org/basic-auth/user/passwd 9
requestId 518 onCompleted main_frame https://httpbingo.org/basic-auth/user/passwd 10
As you can see, the post-auth event sequence is identical, except Firefox re-used the requestId.
Comment 3•10 months ago
|
||
The severity field is not set for this bug.
:robwu, could you have a look please?
For more information, please visit BugBot documentation.
Reporter | ||
Comment 4•10 months ago
|
||
bug 1820807 changes the implementation to introduce another onBeforeRedirect event in onAuthRequired.
Once the other bug is resolved (with the intended behavior), we should update the documentation with the expected event flows (for onAuthRequired and onBeforeRedirect), so that MDN's documentation matches the actual behavior.
Description
•