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

Reply via email to