Hi, I agree with Juan that handling the list of "allowed origins" for CORS filter should be done carefully, since that filter applies to each and every REST API request.
> For completeness, there's already another patch providing SSO for non-GWT > applications, but deployed along with the ovirt-engine and packaged in .war, > no matter if the application itself is non-Java one. > See https://gerrit.ovirt.org/#/c/67206/ . That ^^ new filter is for enginesso.war or a different .war? The general problem is, from an external web application perspective, how to: a, obtain SSO token - reusing some "externally given" token is generally a bad idea, unless the external application is "under control" of enclosing application that issued the token, for example => UI plugins - therefore, requesting new token per each external application should be the way to go, in general b, call REST API with SSO token - using HTTP basic auth is generally a bad idea (many reasons) c, (optional, just an idea) tighter UI integration - add infra to manage "trusted" web applications, these will show up on the oVirt welcome page - when accessing "trusted" web application (via the welcome page), get current user's SSO token and pass it to that application As for CORS "allowed origins" list: this is currently managed through `CORSAllowedOrigins` Engine config value. This list is read only once (on 1st CORSSupportFilter access). So any change in following options: CORSSupport # true or false CORSAllowedOrigins # comma separated list of protocol://domain:port requires Engine restart, which isn't too flexible. After we acknowledge that CORS is a necessary feature of oVirt Engine (in relation to SSO/REST usage from external application context), we should introduce a better interface to manage CORS settings, *without* having to restart Engine on each change. Regards, Vojtech ----- Original Message ----- > From: "Juan Hernández" <[email protected]> > To: "Marek Libra" <[email protected]>, "devel" <[email protected]> > Sent: Monday, December 12, 2016 9:22:03 AM > Subject: Re: [ovirt-devel] SSO/CORS for remote non-Java apps > > On 12/12/2016 08:03 AM, Marek Libra wrote: > > The proposed way is: > > - use CORS filter for enginesso.war (https://gerrit.ovirt.org/68062) > > - at host installation, add the host to CORSAllowedOrigins > > - on engine host: # engine-config -s 'CORSAllowedOrigins=[host IPs]' > > > > So if Cockpit's plugin accesses the oVirt REST API, CORS will work.' > > > > Note that adding the host with 'engine-config' isn't ideal, as it would > require to restart the engine whenever a host is installed. In addition > you would also need to find a way to update the configuration when a > host is removed. > > I think that it would be better to change the CORS filter so that it > gets the list of allowed origins running a query that returns the list > of hosts. That needs to be done with care, probably caching it somehow, > as otherwise that query would run once for each API request, killing > performance. I suggest something like this: > > 1. Store in the backend, in memory, the list of allowed origins. > > 2. During startup populate that with the list of hosts. > > 3. Whenever a host is added or removed (with the corresponding backend > command) update that list. > > 4. Add a new backend query that returns that list stored in memory > (without database access). > > 5. Modify the CORS filter so that it executes that query to get the list > of allowed hosts. Runing this query should be avoided for non-CORS requests. > > > On Fri, Dec 9, 2016 at 3:42 PM, Marek Libra <[email protected] > > <mailto:[email protected]>> wrote: > > > > Hi, > > > > How can external, purely JavaScript application, running in a > > browser and served from non-engine host access the oVirt REST API? > > > > Recent SSO implementation does not provide CORS support. It can be > > fixed by https://gerrit.ovirt.org/68062 . > > > > How shall this support for external application look like? > > > > More details are in our so far discussion with Juan bellow. > > > > For completeness, there's already another patch providing SSO for > > non-GWT applications, but deployed along with the ovirt-engine and > > packaged in .war, no matter if the application itself is non-Java one. > > See https://gerrit.ovirt.org/#/c/67206/ > > <https://gerrit.ovirt.org/#/c/67206/> . > > > > ---------- Forwarded message ---------- > > From: *Juan Hernández* <[email protected] > > <mailto:[email protected]>> > > Date: Fri, Dec 9, 2016 at 2:40 PM > > Subject: Re: CORSSuport > > To: Marek Libra <[email protected] <mailto:[email protected]>> > > > > > > On 12/09/2016 02:26 PM, Marek Libra wrote: > > > Thanks for your quick response and fast action :-) > > > > > > I'm working on integration of oVirt to Cockpit, ideally purely JS > > > application (Cockpit's plugin) will access oVirt REST API without > > > using > > > any proxy. > > > The Cockpit is running on an oVirt host. > > > > > > IIUC, the OAuth token is *required* to access the REST API. > > > > > > > The OAuth token isn't strictly required at the moment: the API also > > supports HTTP basic authentication. The OAuth token will be required > > when support for version 3 of the API and support for basic > > authentication are removed. We intend to remove those two things in > > version 4.2 of oVirt. > > > > > If so, there are just two options for external javascript application > > > willing to access the API: > > > [1] either reuse "externaly given Bearer token'' - some oVirt web > > > application served from engine node would need to provide it to the > > > JS > > > application running elsewhere > > > [2] or call the /ovirt-engine/sso service to get one > > > > > > Regarding [1], I havn't tried it yet, but from checking the SSO > > > filters > > > in ovirt-engine, this might work since it's retrieving session based > > > on > > > token. What do you think? > > > > > > Regarding [2], the patch you posted would be needed. > > > > > > Do I miss something? > > > > > > > There is option 3: use HTTP basic authentication. But that won't work > > with oVirt 4.2 or newer, so doesn't look like a reasonable thing. > > > > I think that the only reasonable option is [2]. However, we can't (or > > should not) just configure the existing CORS support to accept any > > origin (CORSAllowedOrigins=*) as that isn't secure. We will probably > > need to have a dynamic list of allowed origins: the list of hosts. That > > would need extensive changes to the CORS filter. > > > > So, for your experiments, you can just move the current filter so that > > it can be used by the SSO application. But for real use we need to > > think > > a bit deeper on how should CORS support work. I'd suggest that you open > > this discussion to a wider audience, within your team, or in the > > upstream mailing list. > > > > > Thanks > > > > > > On Fri, Dec 9, 2016 at 1:53 PM, Juan Hernández <[email protected] > > > <mailto:[email protected]> > > > <mailto:[email protected] <mailto:[email protected]>>> wrote: > > > > > > On 12/09/2016 01:38 PM, Marek Libra wrote: > > > > Hi Juan, > > > > > > > > I'm trying to set up CORS on ovirt-engine following > > instructions in > > > > https://gerrit.ovirt.org/#/c/36367/ > > <https://gerrit.ovirt.org/#/c/36367/> > > > <https://gerrit.ovirt.org/#/c/36367/ > > <https://gerrit.ovirt.org/#/c/36367/>> . > > > > But I can't get the 'Access-Control-Allow-Origin' to be > > returned. > > > > > > > > -- My ovirt-engine: > > > > > > > > > > > ovirt-engine-4.1.0-0.0.master.20161121231311.git19a0953.el7.centos.noarch > > > > > > > > -- On engine host: > > > > # engine-config -s CORSSupport=true > > > > # engine-config -s 'CORSAllowedOrigins=*' > > > > # systemctl restart ovirt-engine > > > > > > > > > > > > -- My JS call looks like: > > > > > > > > var url = baseUrl + > > > > > > > > > > > '/sso/oauth/token?grant_type=urn:ovirt:params:oauth:grant-type:http&scope=ovirt-app-api'; > > > > $.ajax(url, { > > > > type: 'GET', > > > > headers: { > > > > 'Accept': 'application/json', > > > > 'Authorization': 'Basic ' + window.btoa(user + ':' + > > pwd), > > > > 'Content-Type': 'application/xml' > > > > } }) > > > > .then(data => { > > > > logDebug(`login successful: ${JSON.stringify(data)}`); > > > > Promise.resolve(data) > > > > }) > > > > .catch(data => { > > > > logDebug('Ajax failed: ' + JSON.stringify(data)); > > > > return Promise.reject(data); > > > > }); > > > > > > > > > > > > -- From Chrome: > > > > Request > > > > > > > > > > > URL:https://engine.local/ovirt-engine/sso/oauth/token?grant_type=urn:ovirt:params:oauth:grant-type:http&scope=ovirt-app-api > > > > <https://engine.local/ovirt-engine/sso/oauth/token?grant_type=urn:ovirt:params:oauth:grant-type:http&scope=ovirt-app-api> > > > > > > > <https://engine.local/ovirt-engine/sso/oauth/token?grant_type=urn:ovirt:params:oauth:grant-type:http&scope=ovirt-app-api > > > > <https://engine.local/ovirt-engine/sso/oauth/token?grant_type=urn:ovirt:params:oauth:grant-type:http&scope=ovirt-app-api>> > > > > Request Method:OPTIONS > > > > Status Code:200 OK > > > > Remote Address:192.168.122.100:443 > > <http://192.168.122.100:443> <http://192.168.122.100:443> > > > <http://192.168.122.100:443> > > > > > > > > Response Headers: > > > > HTTP/1.1 200 OK > > > > Date: Fri, 09 Dec 2016 11:56:08 GMT > > > > Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips > > > > Content-Encoding: gzip > > > > Set-Cookie: locale=en_US; path=/; HttpOnly; > > Max-Age=2147483647 <tel:2147483647>; > > > > Expires=Wed, 27-Dec-2084 15:10:15 GMT > > > > X-XSS-PROTECTION: 1; MODE=BLOCK > > > > X-CONTENT-TYPE-OPTIONS: NOSNIFF > > > > X-FRAME-OPTIONS: SAMEORIGIN > > > > Content-Type: application/json > > > > Content-Length: 116 > > > > Keep-Alive: timeout=5, max=100 > > > > Connection: Keep-Alive > > > > > > > > Request Headers: > > > > OPTIONS > > > > > > > > > > > /ovirt-engine/sso/oauth/token?grant_type=urn:ovirt:params:oauth:grant-type:http&scope=ovirt-app-api > > > > HTTP/1.1 > > > > Host: engine.local > > > > Connection: keep-alive > > > > Access-Control-Request-Method: GET > > > > Origin: https://192.168.122.141:9090 > > > > User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64) > > AppleWebKit/537.36 > > > > (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36 > > > > Access-Control-Request-Headers: authorization, content-type > > > > Accept: */* > > > > Referer: > > > > > https://192.168.122.141:9090/cockpit/@localhost/machines/index.html > > <https://192.168.122.141:9090/cockpit/@localhost/machines/index.html> > > > > > <https://192.168.122.141:9090/cockpit/@localhost/machines/index.html > > <https://192.168.122.141:9090/cockpit/@localhost/machines/index.html>> > > > > Accept-Encoding: gzip, deflate, sdch, br > > > > Accept-Language: en-GB,en-US;q=0.8,en;q=0.6 > > > > > > > > -- restapi.war/WEB-INF/web.xml contains CORSSupportFilter > > > configuration > > > > but > > > > -- enginesso.war/WEB-INF/web.xml doesn't > > > > > > > > How is it supposed to work, please? > > > > Is there already suggested procedure to have CORS running? > > > > > > > > Thanks, > > > > Marek > > > > > > > > > > The CORS support was intended only for the API, thus it isn't > > available > > > for other applications. If you want to be able to use it in > > the SSO > > > application, then it needs to be moved to a module where it can > > > be > > > shared. Something like this: > > > > > > core: Move CORS filter from API to utils > > > https://gerrit.ovirt.org/68062 <https://gerrit.ovirt.org/68062> > > > > > > If this is more than an experiment, then I'd suggest you take > > ownership > > > of that patch. > > > > > > > > > > > > > > > > > > _______________________________________________ > > Devel mailing list > > [email protected] > > http://lists.phx.ovirt.org/mailman/listinfo/devel > > > > _______________________________________________ > Devel mailing list > [email protected] > http://lists.phx.ovirt.org/mailman/listinfo/devel > _______________________________________________ Devel mailing list [email protected] http://lists.phx.ovirt.org/mailman/listinfo/devel
