Bug 1031597 - REST-API: Session based authentication in 3.4 is broken
Summary: REST-API: Session based authentication in 3.4 is broken
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Red Hat Enterprise Virtualization Manager
Classification: Red Hat
Component: ovirt-engine-restapi
Version: 3.4.0
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
: 3.4.0
Assignee: Alon Bar-Lev
QA Contact: movciari
URL:
Whiteboard: integration
Depends On:
Blocks: 961677 1057367 rhev3.4beta 1142926
TreeView+ depends on / blocked
 
Reported: 2013-11-18 11:14 UTC by Elena
Modified: 2014-09-18 12:24 UTC (History)
17 users (show)

Fixed In Version: ovirt-3.4.0-alpha1
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2014-06-12 14:05:53 UTC
oVirt Team: ---
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
oVirt gerrit 21566 0 None None None Never
oVirt gerrit 21955 0 None None None Never

Description Elena 2013-11-18 11:14:01 UTC
1. {'Prefer': 'persistent-auth', 'Session-TTL': 3600, 'Authorization': 'Basic YWRtaW5AaW50ZXJuYWw6MTIzNDU2'}
2. Got JSESSIONID=vA2fNxzTsJTihKyW+r4PuE7P; Path=/; Secure
3. {'Prefer': 'persistent-auth', 'Session-TTL': 3600, 'Cookie': 'JSESSIONID=vA2fNxzTsJTihKyW+r4PuE7P; Path=/; Secure'}
 
Results: error 401

Comment 1 Michael Pasternak 2013-11-18 11:42:10 UTC
the problem is that when servlet redirects from /api to /ovirt-engine/api
cookie produced with "Path=/", sending this cookie back to server from /api
makes ContextDispacher to ignore it.

Comment 4 Michael Pasternak 2013-11-18 12:06:28 UTC
looks like this is a 'curl' bug, - parameters order issue.

Comment 7 Michael Pasternak 2013-11-18 13:49:22 UTC
(In reply to Michael Pasternak from comment #4)
> looks like this is a 'curl' bug, - parameters order issue.

works a expected, reproducer was using different base URIs.

Comment 8 Michael Pasternak 2013-11-19 12:38:44 UTC
actually after thinking about this a bit, we should consider allowing one
that authenticated against /api to browse /ovirt-engine/api as well as internal
api links has  /ovirt-engine/api as base URI

Comment 9 Alon Bar-Lev 2013-11-19 12:46:04 UTC
(In reply to Michael Pasternak from comment #8)
> actually after thinking about this a bit, we should consider allowing one
> that authenticated against /api to browse /ovirt-engine/api as well as
> internal
> api links has  /ovirt-engine/api as base URI

Right. But I still do not understand how it is not working while the cookie is gotten as:

Set-Cookie: JSESSIONID=97f9XIGi3O-HZQbBpVR+E5Vp.undefined; Path=/

What is the missing bit?

Comment 14 Alon Bar-Lev 2013-11-23 20:31:32 UTC
Not that I understand why forward should not behave exactly as if user accessed the target context... But this is not our to decide.

I submitted a solution that is based on jboss rewrite valve instead of j2ee forward. Can you please check it out?

Thanks!

Comment 15 Michael Pasternak 2013-11-24 07:16:54 UTC
(In reply to Alon Bar-Lev from comment #14)
> Not that I understand why forward should not behave exactly as if user
> accessed the target context... But this is not our to decide.
> 
> I submitted a solution that is based on jboss rewrite valve instead of j2ee
> forward. Can you please check it out?
> 
> Thanks!

yesterday night i was exploring the same, just at Apache mod_rewrite,

(i wish i knew we already doing the same in virtual-server for
^/RHEVManager(.*)$, it would save couple of hours for me, btw why do we need
ForwardServlet then?)

Comment 16 Alon Bar-Lev 2013-11-24 07:50:10 UTC
(In reply to Michael Pasternak from comment #15)
> (In reply to Alon Bar-Lev from comment #14)
> > Not that I understand why forward should not behave exactly as if user
> > accessed the target context... But this is not our to decide.
> > 
> > I submitted a solution that is based on jboss rewrite valve instead of j2ee
> > forward. Can you please check it out?
> > 
> > Thanks!
> 
> yesterday night i was exploring the same, just at Apache mod_rewrite,
> 
> (i wish i knew we already doing the same in virtual-server for
> ^/RHEVManager(.*)$, it would save couple of hours for me, btw why do we need
> ForwardServlet then?)

The first priority is to solve issues at application level, so that if we want we can be installed at shared environment.

I sincerely tried to understand the root cause of the problem since first reported (comment#5)... once I understood (comment#12) what the problem is I could look into non java solutions.

Thanks!

Comment 17 Juan Hernández 2013-12-02 15:24:43 UTC
The additional redirect introduced by the patch breaks all the clients that don't support redirects.

Comment 18 Alon Bar-Lev 2013-12-02 15:37:45 UTC
(In reply to Juan Hernández from comment #17)
> The additional redirect introduced by the patch breaks all the clients that
> don't support redirects.

you mean redirect of /api to /api/?

Comment 19 Juan Hernández 2013-12-02 15:40:34 UTC
Yes.

Comment 20 Alon Bar-Lev 2013-12-02 15:47:05 UTC
Michael,

Please provide impact analysis of that:

1. client does not respect http redirect.

2. client access /api directly and not /api/

If we have a problem the next alternatives are:

1. install api war twice at /api and at /ovirt-engine/api

2. implement our own valve into jboss, one that respect the ';' correctly.

Thanks,

Comment 21 Michael Pasternak 2013-12-03 12:17:50 UTC
(In reply to Alon Bar-Lev from comment #20)
> Michael,
> 
> Please provide impact analysis of that:
> 
> 1. client does not respect http redirect.
> 
> 2. client access /api directly and not /api/

why do you ask this?, i was sure your last patch addresses all these issues,
also if you remember i can't verify this as it's does not work on
development env. (and you confirmed that it's works as expected),

IMHO doing analysis after patch was merged does not make much sense.

> 
> If we have a problem the next alternatives are:
> 
> 1. install api war twice at /api and at /ovirt-engine/api

i suggest that a while ago, but still prefer #2.

> 
> 2. implement our own valve into jboss, one that respect the ';' correctly.

i mentioned before that jboss "rewrite" is better approach as it does not
leave the container (our domain).

> 
> Thanks,

Comment 22 Alon Bar-Lev 2013-12-03 12:20:34 UTC
(In reply to Michael Pasternak from comment #21)
> (In reply to Alon Bar-Lev from comment #20)
> > Michael,
> > 
> > Please provide impact analysis of that:
> > 
> > 1. client does not respect http redirect.
> > 
> > 2. client access /api directly and not /api/
> 
> why do you ask this?, i was sure your last patch addresses all these issues,
> also if you remember i can't verify this as it's does not work on
> development env. (and you confirmed that it's works as expected),
> 
> IMHO doing analysis after patch was merged does not make much sense.
> 

The redirect between /api to /api/ was know issue, knowing that we progressed the merge.

To be in the safe side, I ask you again to provide analysis maybe this is not important to perform any change.

Can you please?

> > 
> > If we have a problem the next alternatives are:
> > 
> > 1. install api war twice at /api and at /ovirt-engine/api
> 
> i suggest that a while ago, but still prefer #2.
> 
> > 
> > 2. implement our own valve into jboss, one that respect the ';' correctly.
> 
> i mentioned before that jboss "rewrite" is better approach as it does not
> leave the container (our domain).
> 

Writing code is the last option I would like to take.

Comment 25 Michael Pasternak 2013-12-03 12:44:31 UTC
(In reply to Alon Bar-Lev from comment #24)
> (In reply to Michael Pasternak from comment #23)
> > this is what i see:
> > 
> > send: 'GET /api HTTP/1.1\r\nHost: ....redhat.com\r\nAccept-Encoding:
> > identity\r\nFilter: False\r\nPrefer: persistent-auth\r\nContent-type:
> > application/xml\r\nAccept: application/xml\r\nAuthorization: Basic
> > ....\r\n\r\n'
> > 
> > reply: 'HTTP/1.1 301 Moved Permanently\r\n'
> > header: Date: Tue, 03 Dec 2013 12:39:29 GMT
> > header: Server: Apache/2.4.6 (Fedora) OpenSSL/1.0.0-fips
> > header: Location: https:/....redhat.com/api/
> > header: Content-Length: 243
> > header: Content-Type: text/html; charset=iso-8859-1
> > body:
> > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
> > <html><head>
> > <title>301 Moved Permanently</title>
> > </head><body>
> > <h1>Moved Permanently</h1>
> > <p>The document has moved <a
> > href="https://....redhat.com/api/">here</a>.</p>
> > </body></html>
> 
> Correct... there is single redirection from /api to /api/.

automatic redirect is not a must by spec [1], also it should not
work for anything, but GET/HEAD.

[1] http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2

Comment 26 Michael Pasternak 2013-12-03 13:02:05 UTC
(In reply to Michael Pasternak from comment #25)
> (In reply to Alon Bar-Lev from comment #24)
> > (In reply to Michael Pasternak from comment #23)
> > > this is what i see:
> > > 
> > > send: 'GET /api HTTP/1.1\r\nHost: ....redhat.com\r\nAccept-Encoding:
> > > identity\r\nFilter: False\r\nPrefer: persistent-auth\r\nContent-type:
> > > application/xml\r\nAccept: application/xml\r\nAuthorization: Basic
> > > ....\r\n\r\n'
> > > 
> > > reply: 'HTTP/1.1 301 Moved Permanently\r\n'
> > > header: Date: Tue, 03 Dec 2013 12:39:29 GMT
> > > header: Server: Apache/2.4.6 (Fedora) OpenSSL/1.0.0-fips
> > > header: Location: https:/....redhat.com/api/
> > > header: Content-Length: 243
> > > header: Content-Type: text/html; charset=iso-8859-1
> > > body:
> > > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
> > > <html><head>
> > > <title>301 Moved Permanently</title>
> > > </head><body>
> > > <h1>Moved Permanently</h1>
> > > <p>The document has moved <a
> > > href="https://....redhat.com/api/">here</a>.</p>
> > > </body></html>
> > 
> > Correct... there is single redirection from /api to /api/.
> 
> automatic redirect is not a must by spec [1], also it should not
> work for anything, but GET/HEAD.
> 
> [1] http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2

Apache HttpClient implements it (sdk-java is alright), httplib (Python 2.7.5)
is not(e.g it breaks sdk-python).

Comment 27 Alon Bar-Lev 2013-12-03 13:06:53 UTC
ok, working on duplicate the api into two wars in ear at /api and /ovirt-engine/api.

Comment 28 Juan Hernández 2013-12-03 13:09:12 UTC
If the hrefs generated by the API are going to be always /ovirt-engine/api regardless of the URL actually used by the client why not just do this?

<Location /api>
  ProxyPass ajp://127.0.0.1/api
</Location>

<Location /ovirt-engine/api>
  ProxyPass ajp://127.0.0.1/ovirt-engine/api
</Location>

Comment 29 Juan Hernández 2013-12-03 13:12:35 UTC
A more correct solution, will be to pass the actual URL to the API, so it can generate the correct hrefs:

<Location /api>
  ProxyPass ajp://127.0.0.1/api
  RequestHeader set X-RESTAPI-Prefix /api
</Location>

<Location /ovirt-engine/api>
  ProxyPass ajp://127.0.0.1/api
  RequestHeader set X-RESTAPI-Prefix /ovirt-engine/api
</Location>

The RESTAPI should then take the value of this header and generate the hrefs accordingly.

Comment 30 Alon Bar-Lev 2013-12-03 13:17:23 UTC
(In reply to Juan Hernández from comment #29)
> A more correct solution, will be to pass the actual URL to the API, so it
> can generate the correct hrefs:
> 
> <Location /api>
>   ProxyPass ajp://127.0.0.1/api
>   RequestHeader set X-RESTAPI-Prefix /api
> </Location>
> 
> <Location /ovirt-engine/api>
>   ProxyPass ajp://127.0.0.1/api
>   RequestHeader set X-RESTAPI-Prefix /ovirt-engine/api
> </Location>
> 
> The RESTAPI should then take the value of this header and generate the hrefs
> accordingly.

I am fine with either, michael?

Comment 31 Michael Pasternak 2013-12-03 13:18:09 UTC
(In reply to Juan Hernández from comment #29)
> A more correct solution, will be to pass the actual URL to the API, so it
> can generate the correct hrefs:
> 
> <Location /api>
>   ProxyPass ajp://127.0.0.1/api
>   RequestHeader set X-RESTAPI-Prefix /api
> </Location>
> 
> <Location /ovirt-engine/api>
>   ProxyPass ajp://127.0.0.1/api
>   RequestHeader set X-RESTAPI-Prefix /ovirt-engine/api
> </Location>
> 
> The RESTAPI should then take the value of this header and generate the hrefs
> accordingly.

1.what about RESTeasy resource lookups? they using war-root to get-uri-info
  and process it.
2.what about URL parameters?

Comment 32 Alexander Wels 2013-12-03 13:19:49 UTC
Strange question, but wouldn't this work?

<Location /api>
  ProxyPass ajp://127.0.0.1/ovirt-engine/api
  RequestHeader set X-RESTAPI-Prefix /api
</Location>

<Location /ovirt-engine/api>
  ProxyPass ajp://127.0.0.1/ovirt-engine/api
  RequestHeader set X-RESTAPI-Prefix /ovirt-engine/api
</Location>

Basically in apache point both /api and /ovirt-engine/api to /ovirt-engine/api in jboss? The proxy should automatically rewrite any absolute URLs to match what it is supposed to be.

Comment 33 Juan Hernández 2013-12-03 13:27:10 UTC
(In reply to Michael Pasternak from comment #31)
> 1.what about RESTeasy resource lookups? they using war-root to get-uri-info
>   and process it.
> 2.what about URL parameters?

This two questions need to be studied. But I think that they shouldn't be a problem.

(In reply to Alexander Wels from comment #32)
> Basically in apache point both /api and /ovirt-engine/api to
> /ovirt-engine/api in jboss? The proxy should automatically rewrite any
> absolute URLs to match what it is supposed to be.

The proxy rewrites the request URL, and can also rewrite the URLs in the response headers, but it doesn't rewrite the URLs in the body of the response, specially when the body is XML or JSON. That is the task of the application.

Note that I just invented the X-RESTAPI-Prefix header, is would need to be implemented.

Comment 34 Alon Bar-Lev 2013-12-03 13:30:48 UTC
A patch to perform this using war duplication last before code change.

Comment 35 Alexander Wels 2013-12-03 13:31:48 UTC
So if I establish a session on /api (apache) and I get back some response that points me to /ovirt-engine/api (apache). The cookie should be valid for URLs as the session was established in the /ovirt-engine/api context in jboss. The only issue could be the cookie domain but I think the proxy should take care of that.

Comment 36 Alon Bar-Lev 2013-12-03 13:34:37 UTC
(In reply to Alexander Wels from comment #35)
> So if I establish a session on /api (apache) and I get back some response
> that points me to /ovirt-engine/api (apache). The cookie should be valid for
> URLs as the session was established in the /ovirt-engine/api context in
> jboss. The only issue could be the cookie domain but I think the proxy
> should take care of that.

in the patch introduced in comment#34, if application accesses /api it gets /api uris in response, if it accesses /ovirt-engine/api it gets /ovirt-engine/api, so no need to share cookies or anything between these two contexts.

Comment 37 Juan Hernández 2013-12-03 13:39:12 UTC
Take into account that deploying the same application twice in the same application server means that the classes will be loaded twice. This invalidates any locking that depends on singletons. Verify carefully that it isn't a problem before applying that solution.

Comment 38 Michael Pasternak 2013-12-03 13:50:45 UTC
(In reply to Juan Hernández from comment #37)
> Take into account that deploying the same application twice in the same
> application server means that the classes will be loaded twice. This
> invalidates any locking that depends on singletons. Verify carefully that it
> isn't a problem before applying that solution.

it should be addressed by the classloader isolation.

Comment 39 Juan Hernández 2013-12-03 13:55:16 UTC
Usually it is, but in some cases it isn't:

import from.my.shared.library.SomeResource;

class FromMyWebApp {
  private Some resource resource = ...;

  public synchronized void doSomethingThatRequiresExclusiveAccessToResource() {
     // Will work fine when loaded once, and will fail, without trace,
     // when loaded twice.
     resource.doSomething();
  }
}

We don't probably have this behavior in the RESTAPI application.

Comment 40 Alon Bar-Lev 2013-12-03 16:21:43 UTC
Guys, we need an answer about the method. If two instances of war is not solution I will fallback to proxy attempt.

Thanks!

Comment 41 Michael Pasternak 2013-12-04 12:17:45 UTC
(In reply to Alon Bar-Lev from comment #40)
> Guys, we need an answer about the method. If two instances of war is not
> solution I will fallback to proxy attempt.
> 
> Thanks!

Juan has a point, i'd run a full automation-cycle on the /api + /ovirt-engine/api
when two apps deployed side by side,

thanks.

Comment 45 Sandro Bonazzola 2014-01-14 08:44:00 UTC
ovirt 3.4.0 alpha has been released

Comment 46 Itamar Heim 2014-06-12 14:05:53 UTC
Closing as part of 3.4.0


Note You need to log in before you can comment on or make changes to this bug.