Default CORS allowed origins can be generated dynamically, please have a
look at https://gerrit.ovirt.org/#/c/68529/ .
With this patch, all hosts are allowed.

The CORSSupportFilter delegates all processing to the eBay's CORSFilter
which needs to be reinitialized if the list of origins is changed.
So for simplicity, it's better to keep optimization on CORSSupportFilter
and not in the backend query.

Regarding performance, there's almost no processing if CorsSupported=false.
So it's ok.
If otherwise, the cache of host list must be maintained (host add/remove).
To avoid coupling this code with backend commands, the list is re-read at
most once per minute and the CORSFilter is optionally reinitialized.

Recently the CORSSupportFilter works already fine for REST API. For
enginesso.war some more work remains..
But once this is done, external applications served from hosts shall be
able to access both API and SSO.

And host add/remove will not require engine restart.


On Mon, Dec 12, 2016 at 7:42 PM, Vojtech Szocs <[email protected]> wrote:

> 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.ovirt.org/mailman/listinfo/devel

Reply via email to