Open Bug 1847637 Opened 11 months ago Updated 10 months ago

Event flow after webRequest.onAuthRequired does not match documention and is not interoperable with Chrome

Categories

(WebExtensions :: Request Handling, task, P3)

task

Tracking

(Not tracked)

People

(Reporter: robwu, Unassigned)

References

Details

Attachments

(1 file)

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

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.
  • 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.
  • 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.
  • 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 by onBeforeRequest.
    • 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.

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:

  1. Load the extension (at about:debugging in Firefox, or chrome://extensions/ in Chrome).
  • The extension will print every webRequest event.
  1. Inspect the background page (in Chrome, the Developer Mode checkbox needs to be enabled first).
  2. Allow the extension access to Private Browsing mode (via the extension card in about:addons in Firefox, via a checkbox at chrome://extensions/ in Chrome).
  3. Open a private browsing window.
  4. 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.
  1. View the console from step 1 to inspect the events.
  2. To test again, close the private browsing window (which will clear the auth cache) and restart from step 4.

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.

See Also: → 1820807

The severity field is not set for this bug.
:robwu, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(rob)

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.

Severity: -- → N/A
Type: defect → task
Flags: needinfo?(rob)
Priority: -- → P3
See Also: → 1852258
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: