[Engine-devel] Proposal to make REST API more webapp-friendly
Oved Ourfalli
ovedo at redhat.com
Wed Apr 17 10:29:09 UTC 2013
----- Original Message -----
> From: "Vojtech Szocs" <vszocs at redhat.com>
> To: "Oved Ourfalli" <ovedo at redhat.com>
> Cc: "Juan Hernandez" <jhernand at redhat.com>, "engine-devel" <engine-devel at ovirt.org>
> Sent: Wednesday, April 17, 2013 1:25:06 PM
> Subject: Re: [Engine-devel] Proposal to make REST API more webapp-friendly
>
> Hi Oved, thanks for your feedback!
>
> > We currently return the JSESSIONID also using HTTP headers. We currently
> > return the jsession id also as part of the response HTTP headers, but the
> > client still needs to pass a cookie with the appropriate value in order
> > for the REST session to work. Isn't that enough to cope with this issue?
>
> Right, currently REST API responds with JSESSIONID cookie + separate
> JSESSIONID response header, both carrying session ID value.
>
> As I wrote in my original email: JavaScript running at
> [http://example.com/webapp] *cannot* get/set cookies from requests at
> [http://example.com/restapi]
>
> So WebAdmin cannot get/set REST API JSESSIONID cookie directly, which is why
> it uses separate JSESSIONID response header in order to *read* the session
> ID value. As for sending JSESSIONID cookie, WebAdmin currently relies on
> standard cookie-handling implemented in browsers: all cookies for location X
> [http://example.com/restapi] will be part of any request to location X. So
> it's the browser who sets JSESSIONID cookie for REST API request, not
> WebAdmin.
>
> To answer your question, currently it's enough to work around the cookie
> access limitation, but it's not good enough in my opinion (from
> JavaScript/webapp perspective)..
>
> > If not, then we might be able to do option #2:
> > Today, we keep the engine session ID on the HTTP session attributes.
> > So, we can support either passing the cookie with the JSESSIONID (taking
> > the engine session ID from the http session), or passing the engine
> > session ID as HTTP header (assuming we would also return the engine
> > session ID upon first REST request).
>
> Well, the problem I described only relates to the way how JSESSIONID value is
> transmitted between client and server: currently using cookies, so REST API
> client has to do cookie handling.
>
> It would be really great if I could tell REST API to use plain (i.e. *not*
> Set-Cookie & Cookie) HTTP header, for example "JSESSIONID", for the purpose
> of transmitting session ID value between client and server.
>
> For example, the request to acquire session would be:
>
> GET /api HTTP/1.1
> Host: www.example.org
> Prefer: use-jsessionid-header
> JSESSIONID: xxx
>
> [Feel free to replace "use-jsessionid-header" with anything you like. If
> client doesn't specify "use-jsessionid-header", server expects "Cookie"
> header by default to preserve compatibility.]
>
> And the response would be:
>
> HTTP/1.1 200 OK
> JSESSIONID: xxx
>
> [If client didn't specify "use-jsessionid-header", server would use
> "Set-Cookie" header by default to preserve compatibility.]
>
> > This approach is problematic, as it might work well now, when the only
> > attribute we use is the engine session ID, but in the future that might
> > not be the case.
> > If it is important enough (i.e., you can't really work with option #1) ,
> > then we can make a decision to save the attributes on the engine session,
> > rather than on the HTTP session.
> > So, we would start by supporting them both together, adding new attributes
> > only to the engine session, and in the future deprecating the use of
> > cookies, and only supporting HTTP headers.
>
> I think you can keep the current implementation, i.e. use REST API
> HttpSession to store Engine session ID value.
>
> The only difference would be, when REST API receives the request, it looks
> for "Prefer:use-jsessionid-header", and if it's present, it uses
> "JSESSIONID" header value to look up HttpSession in some way (not sure about
> implementation details, though, but this should be possible to do).
>
> So, what do you think?
>
As far as I saw, the handling of the cookie is done before the REST code, and that's why we need the cookie.
Perhaps there is a way to make jboss take the JSESSIONID from the HTTP header, and not the cookie, but I didn't find a way to do that yet.
> Vojtech
>
>
> ----- Original Message -----
> From: "Oved Ourfalli" <ovedo at redhat.com>
> To: "Vojtech Szocs" <vszocs at redhat.com>
> Cc: "engine-devel" <engine-devel at ovirt.org>, "Juan Hernandez"
> <jhernand at redhat.com>, "Michael Pasternak" <mpastern at redhat.com>
> Sent: Wednesday, April 17, 2013 11:13:12 AM
> Subject: Re: [Engine-devel] Proposal to make REST API more webapp-friendly
>
>
>
> ----- Original Message -----
> > From: "Vojtech Szocs" <vszocs at redhat.com>
> > To: "engine-devel" <engine-devel at ovirt.org>
> > Sent: Monday, April 15, 2013 2:04:24 PM
> > Subject: [Engine-devel] Proposal to make REST API more webapp-friendly
> >
> > Hi guys,
> >
> > having worked with Engine REST API from web application (JavaScript)
> > perspective, there are things that could be improved to make REST API more
> > webapp-friendly.
> >
> > First of all, webapps are *not* traditional HTTP clients, i.e. they have
> > *not* full control over HTTP processing. There are some standard
> > conventions
> > and behaviors built into web browsers that any REST API implementation
> > should be aware of.
> >
> > --
> >
> > (1) Don't force clients to use cookies for transmitting authentication
> > information! (or don't use cookies at all)
> >
> > Good explanation can be found at
> > [http://www.berenddeboer.net/rest/cookies.html]. Cookies have many
> > disadvantages:
> >
> > * cookie parsing/formatting is not trivial
> > --> extra complexity imposed on REST clients
> >
> > * in addition to Same-Origin Policy
> > [http://en.wikipedia.org/wiki/Same_origin_policy], cookies can be get/set
> > *only* for the given path
> > --> JavaScript running at [http://example.com/webapp] *cannot* get/set
> > cookies from requests at [http://example.com/restapi]
> >
> > * cookies are the primary source of Cross-Site Request Forgery
> > [http://en.wikipedia.org/wiki/Cross-site_request_forgery] attacks
> > --> malicious websites/scripts can forge requests to REST API that will
> > include the cookie, compromising user session
> >
> > Alternative: clients could be given the *option* to use regular HTTP header
> > for transmitting authentication information.
> >
> > For example, webapp could read such (sensitive information) header, store
> > it
> > securely via HTML5 Session Storage
> > [http://en.wikipedia.org/wiki/Web_storage] and implement related HTTP
> > processing on its own, e.g. pass this header for all authenticated requests
> > (instead of pushing this responsibility to browser).
> >
>
> Option #1:
> We currently return the JSESSIONID also using HTTP headers. We currently
> return the jsession id also as part of the response HTTP headers, but the
> client still needs to pass a cookie with the appropriate value in order for
> the REST session to work. Isn't that enough to cope with this issue?
>
> If not, then we might be able to do option #2:
> Today, we keep the engine session ID on the HTTP session attributes.
> So, we can support either passing the cookie with the JSESSIONID (taking the
> engine session ID from the http session), or passing the engine session ID
> as HTTP header (assuming we would also return the engine session ID upon
> first REST request).
>
> This approach is problematic, as it might work well now, when the only
> attribute we use is the engine session ID, but in the future that might not
> be the case.
> If it is important enough (i.e., you can't really work with option #1) , then
> we can make a decision to save the attributes on the engine session, rather
> than on the HTTP session.
> So, we would start by supporting them both together, adding new attributes
> only to the engine session, and in the future deprecating the use of
> cookies, and only supporting HTTP headers.
>
> cc-ed Juan and Michael, as they might have some input on that.
>
>
> > --
> >
> > (2) Straight-forward HTTP Basic Auth has some drawbacks!
> >
> > HTTP Basic Auth [http://en.wikipedia.org/wiki/Basic_access_authentication]
> > over (non-secure) HTTP connection means sending user credentials
> > (username/password/domain) in easy-to-decode cleartext, i.e. the value is
> > *not* encrypted or hashed in any way. Using secure lower-level protocol
> > (SSL) fixes the consequence, rather than the root cause of the
> > confidentiality issue.
> >
> > Furthermore, browsers typically remember HTTP Basic Auth information
> > (either
> > via browser-specific popup, or via XmlHttpRequest) until the browser window
> > is closed. This means the webapp has no control over HTTP Basic Auth header
> > after it has been set! This is the reason why it's hard to implement
> > "logout" functionality in webapps when using HTTP Basic Auth.
> >
> > Last but not least, HTTP Basic Auth is vulnerable to Replay attacks
> > [http://en.wikipedia.org/wiki/Replay_attack]. Someone between client and
> > server can intercept requests and replay them, compromising user session.
> >
> > Alternative: clients could be given the *option* to use more advanced
> > authentication scheme.
> >
> > I've just read an excellent article at
> > [http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/]
> > which describes easy yet secure authentication scheme inspired by Amazon
> > Web
> > Services REST API authentication
> > [http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html].
> > The idea is simple: collect auth information, hash (sign) it with a private
> > key, and send everything to server. To guard against Replay attacks, just
> > provide some timestamp to enforce request expiry after some time (say, 5-15
> > minutes). Easy and simple!
> >
> > --
> >
> > (3) Support JSON for resource representations!
> >
> > I think this is pretty much obvious. XML has no real advantages over JSON.
> > JSON, on the other hand, has good support in webapps (JavaScript) and maps
> > directly to common data structures (i.e. string, number, boolean, and so
> > on).
> >
> > From webapp perspective, it's much easier and natural to use JSON than to
> > parse/format XML documents.
> >
> > Alternative: clients could be given the *option* to use JSON, in addition
> > to
> > XML representation.
> >
> > --
> >
> > Vojtech
> > _______________________________________________
> > Engine-devel mailing list
> > Engine-devel at ovirt.org
> > http://lists.ovirt.org/mailman/listinfo/engine-devel
> >
> _______________________________________________
> Engine-devel mailing list
> Engine-devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/engine-devel
>
More information about the Engine-devel
mailing list