[Engine-devel] Proposal to make REST API more webapp-friendly
Antoni Segura Puimedon
asegurap at redhat.com
Wed Apr 24 13:11:33 UTC 2013
Incidentally, the other day reading hacker news I happened upon a similar discussion
and article. It might be an interesting lecture to put in perspective our own discussion:
article: http://swaggadocio.com/post/48223179207/why-the-hell-does-your-api-still-use-http-basic-auth
discussion: https://news.ycombinator.com/item?id=5569625
----- 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 3:08:31 PM
> Subject: Re: [Engine-devel] Proposal to make REST API more webapp-friendly
>
> Hi Oved,
>
> >> 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.
>
> I'm also not sure about this, so far I've only found:
> http://stackoverflow.com/questions/5807664/tomcat-how-to-access-session-manager-from-servlet
>
> It seems that the solution is to either provide custom session manager
> implementation in JBoss, or to obtain standard session manager early when
> processing request and create session manually there.
>
> Vojtech
>
>
> ----- Original Message -----
> From: "Oved Ourfalli" <ovedo at redhat.com>
> To: "Vojtech Szocs" <vszocs at redhat.com>
> Cc: "Juan Hernandez" <jhernand at redhat.com>, "engine-devel"
> <engine-devel at ovirt.org>
> Sent: Wednesday, April 17, 2013 12:29:09 PM
> Subject: Re: [Engine-devel] Proposal to make REST API more webapp-friendly
>
>
>
> ----- 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
> >
> _______________________________________________
> 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