Page MenuHomePhabricator

Is support of "cross-domain requests" an intentional prerequisite to SSO integration for enterprise use cases?
Closed, InvalidPublicBUG REPORT

Description

Steps to Reproduce:
MW installations with SSO integration (e.g. simplesaml) where the remote SSO has an unreasonably strict CORS Policy will result in VE producing the "something went wrong" and "try again" errors when the SSO session expires and the underlying javascript error:

[client request] blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."

ref: https://www.mediawiki.org/wiki/Topic:V2qh378y0tj83so8

Actual Results:
Developers whose SSO does not support Cross-Domain" requests will subject users to uninformative errors with VE that are simple to resolve if VE we able to be configured to do a silent non-cross-domain request (to re-establish the SSO session) prior to the cross-domain request that performs the VE function.

Expected Results:

  1. MW documentation should include SSO CORS policy requirements in installation documentation .
  2. it would be wonderful if VE could be resilient enough to help a user through a session restoration prior to and between edit events (launch VE edit and VE save)

Event Timeline

Revansx created this task.Jul 5 2019, 1:46 PM
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptJul 5 2019, 1:46 PM
matmarex added a subscriber: matmarex.EditedJul 9 2019, 2:07 AM

I am having trouble piecing together what actually happens here. Please understand that we're not familiar with your configuration. :)

If I understand correctly, you have some kind of proxy in front of your wiki that intercepts all requests, in particular intercepts api.php as well, and sometimes causes api.php to return a HTTP redirect instead of a normal response with JSON data? I would expect this to break all kinds of tools, not just VisualEditor.

It seems to me that it should instead make api.php return a JSON data with error information, like vanilla MediaWiki would if you lost your cookies while editing (and logging in was required to edit). VisualEditor will then display that error in its interface.

And then you can write a MediaWiki extension to add special handling for your error in VisualEditor , see e.g. https://github.com/wikimedia/mediawiki-extensions-ConfirmEdit/blob/master/resources/ve-confirmedit/ve.init.mw.CaptchaSaveErrorHandler.js. You could stick a login form there or an <iframe> or whatever you need.

Normally, with simpleSAMLphp SSO integration, when the client's session expires, the very next request the client makes from the browser (to a resource on the server) is redirected (by the simpleSAMLphp auth plugin on the server) to the designated SSO site. After the client works through whatever steps are necessary to re-authenticate, the remote SSO returns the client to the application resource that was originally requested. This all works perfectly for the normal mediawiki edit process. The problem with VE seems to be that the request the client is making to the server is done via AJAX in the browser which (from the perspective of the remote SSO) is deemed "cross-domain" and violates the server's CORS policy. If the session is secure, VE has no problems. The problem is when the session needs to be re-established and the user is messing with VE.

Please see the image shown half-way down the page at: https://javascript.info/fetch-crossorigin

You wrote, "It seems to me that it should instead make api.php return a JSON data with error information, like vanilla MediaWiki would if you lost your cookies while editing" -- what are you referring to when you say "It"? .. The remote SSO? .. or VE? .. If you are referring to the remote SSO, there is no altering it. Because It simply refuses to respond to cross-domain

I don't think any special Mediawiki Extensions (written or to-be-written) would solve this basic issue. The remote SSO simply won't respond to VE's request without the added header info clarifying the "Access-Control-Allow-Origin" header. Without this header info, the remote SSO site simply will not respond to requests from VE.

Does that help?

Normally, with simpleSAMLphp SSO integration, when the client's session expires, the very next request the client makes from the browser (to a resource on the server) is redirected (by the simpleSAMLphp auth plugin on the server) to the designated SSO site. After the client works through whatever steps are necessary to re-authenticate, the remote SSO returns the client to the application resource that was originally requested. This all works perfectly for the normal mediawiki edit process. The problem with VE seems to be that the request the client is making to the server is done via AJAX in the browser which (from the perspective of the remote SSO) is deemed "cross-domain" and violates the server's CORS policy. If the session is secure, VE has no problems. The problem is when the session needs to be re-established and the user is messing with VE.

But in this scenario, even if the request wasn't cross-domain (your remote SSO was on the same domain as your wiki), or if the cross-domain request was allowed (you configured your remote SSO to output the required Access-Control-Allow-Origin headers etc.), you would still have the same problem. VE would make a request to save the page, and your wiki (by redirecting to your remote SSO) would respond with an HTML page (presumably with a login form) instead of JSON data. VE would not show the form, because it doesn't expect this kind of a response, and your user would still not be able to log in again or to save the page.

The real problem is not CORS, but rather the fact that you're trying to respond to an AJAX api.php request (which should return JSON data) with an HTML page.

If VE is confounding you, try the same scenario with the AJAX watch star functionality built into MediaWiki. I can't test this, since I don't have any wiki set up that is configured like this, but I expect that if your session expired, clicking the watch star will not add the page to your watchlist, or redirect you, but instead will show an error message.

You wrote, "It seems to me that it should instead make api.php return a JSON data with error information, like vanilla MediaWiki would if you lost your cookies while editing" -- what are you referring to when you say "It"? .. The remote SSO? .. or VE? .. If you are referring to the remote SSO, there is no altering it. Because It simply refuses to respond to cross-domain

I'm sorry if I'm unclear, the terminology is not familiar to me. I was referring to the simpleSAMLphp auth plugin on the server running MediaWiki.


Just to make sure I'm not talking crazy, I googled "simplesamlphp ajax", and found this thread: https://groups.google.com/forum/#!msg/simplesamlphp/xn-FEiT7AkA/zLL1ggZl5bYJ where someone has the same issue as you, and someone else gives the same answer I'm giving you, but with better technical detail:

Olav Morken

Hi,
just to jump into the discussion here. The reason is almost certainly
the AJAX requests. When your SP sends a redirect to the IdP in response
to an AJAX request, it is trying to make the browser send an AJAX
request to a third-party site (the IdP). This runs afoul of the
browsers security model (same-origin restrictions), so the browser
won't follow the redirect.
I'd suggest replacing any requireAuth()-calls in the AJAX endpoints with
isAuthenticated()-calls, and returning an error instead when the user
is logged out. You could then handle that from javascript, e.g. by
redirecting the browser the the IdP properly, or by displaying a
message to the user saying that the user is logged out, and giving them
a login link that they can follow to log back in.

Gotcha. Yes, your "watch" star comparison is exactly right.. and I think you are 100% correct on all additional counts as well. I think this means that the solution to my scenario would need to be two-fold: A) Yes, there is a a CORS policy issue, but also B) even when the CORS Policy is lifted there is an further error handling situation that would be revealed next.

All that said.. I think there is an opportunity here for VE to have a user-configurable default action to take in this error case that is a bit better than merely saying "Something went wrong" per a system message that does not support wikitext [1]. In my perfect world (ha ha) Mediawiki would have a configuration variable that contains a "local system problem resolution url". By which mediawiki and any and all extension could appeal to when "something goes wrong" that has not been provisioned for. This would allow mediawiki to have a default action when say the watch star doesn't respond.. and it would give extensions like VE a page to launch when it finds itself in a "something went wrong" scenario that is beyond its error handling scope.

For the purposes of this (T227329) issue. I think we can close this out. I will try to get the MW core folks to address the watch star scenario and simultaneously petition the VE developers to include some kind of mechanism to allow system owners to provide some kind of help to users who find themselves in this scenario. Thanks!

[1] https://phabricator.wikimedia.org/T227325

matmarex closed this task as Invalid.Jul 19 2019, 9:30 PM

For the purposes of this (T227329) issue. I think we can close this out.

I'll close it then. Good luck!