Force Proxy re-authentication in Chrome Extension

2019-08-27 16:50发布

问题:

I'm making an extension which allows users to store proxy servers with auth credentials (user/pass) and switch between servers. I am listening for the webRequest.onAuthRequired event and when the server challenges for auth, proving the username/password the user has saved, as per the provideCredentialsSync example here: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onAuthRequired#Examples

The problem is that when these credentials are provided, they seem to get saved/cached somewhere in the extension that the developer does not have access to, and then are continually re-used. So, if the extension user then changes their credentials to be incorrect, the browser automatically keeps using the authenticated creds in it's Proxy-Authorization header and the request succeeds. Vice-versa, if authentication fails, and the request is cancelled as per the above example, then the user changes their creds to be correct, the server does not challenge for authentication again and the request fails with no way to offer the new creds.

Chrome also does not allow modification of the outgoing Proxy-Authorization header, meaning it cannot be deleted/changed in the code to force the server to challenge again.

So I suppose the core questions are:

  • Does anyone know where the details are saved when returned from the webRequest.onAuthRequired listener, and is there a way to clear/purge?

  • What actually happens when {cancel: true} is returned and why do all requests to that server then continue to fail without firing another onAuthRequired?

Thanks for any light anyone can shed!

回答1:

The problem is that when these credentials are provided, they seem to get saved/cached somewhere in the extension that the developer does not have access to, and then are continually re-used

Not exactly... Proxy servers do NOT send Auth requests (407 Proxy Authentication Required) on every connection request. They often check that periodically (depending on their set-up).

Browser also may cache (for example in case of Auto-Login in Firefox but Chrome doesn't have it).

Does anyone know where the details are saved when returned from the webRequest.onAuthRequired listener, and is there a way to clear/purge?

The important point is, there is no need for a client to send a different credentials to the same server if the previous one was correct.

Server request credentials:

  • if correct ones are passed, it is allowed and both server and browser keep that for a while
  • if wrong ones are passed, browser doesn't keep it but server may block repeated attempts for a while and then re-request authentication

You can remove & restart webRequest.onAuthRequired but personally I haven't found a real need to do so for new credentials, except when I was testing bad-authentication results during development by intentionally sending wrong credential which should NOT be the case for client use.

webRequest.onAuthRequired is fired whenever server requests it. You can try logging it to see how often the server does it.

Extension code (I mean the developer code, not the browser) may also cache credential (to avoid making async calls and slowing down the authentication and therefore the connection).

Personally, I cache all credentials for all proxies and then respond to auth requests accordingly. Otherwise, you can change the extension code caching object and/or remove & restart webRequest.onAuthRequired.

What actually happens when {cancel: true} is returned and why do all requests to that server then continue to fail without firing another onAuthRequired?

That depends on both extension code and server settings. Server settings may block connections for a period of time after unsuccessful authentication (to prevent Ddos attacks).

Extension code can also check for the right authentication before sending {cancel: true} which kills the connection. In practise, sending {cancel: true} is rarely needed.

There is also a possibility of getting into bad-authentication loop which will cause the connection to fail and can lock up the browser.

In chrome, I would use (do use & must use) a Promise which is the right way to authenticate as the code stops executing until promise is resolved. Using a callback function (that chrome API uses) does not do that which could be the cause of your problem.

To simplify:

  • add webRequest.onAuthRequired
  • On Auth request, start a new Promise to get the correct credentials
  • Prepare for avoiding Bad-Authentication loop


回答2:

I actually never used it, but maybe it is Cache-Control? And here is link to Standard



回答3:

Just call https://developer.chrome.com/extensions/webRequest#method-handlerBehaviorChanged and Chrome asks extension for creds again(You must call it with callback and wait resolving in blocking mode of listener). If you want cancel request, you must do this in onBeforeRequest, because onAuthRequired is optional listener