BBR
BBR

Reputation: 700

Using cookie-based authentication with CloudFront (NOT signed cookies)

I am relatively new to CloudFront, and my company is considering a possibility to move there. We have a bunch of webites with our own cookie-based authentication mechanism, pretty straightforward: login page sets a special cookie, all other requests served when this cookie is present, and denied otherwise.

What we wish from CloudFront is the following:

  1. When a first request to some resource contains this cookie, pass the cookie to the origin server. When there is no cookie, send the request anyway, it is ok to have access denied error returned in this case.
  2. Cache the returned result (if success).
  3. All following requests to the same resource having this cookie should be taken from cache.
  4. Optimally (but optionally), cookie expiration should be checked.
  5. Besides, usual cache-control rules based on headers should apply.
  6. Login page request may be cached or not, this is not important.

I tried to use cookie whitelist, but the cookie contents is different for different logins, so same resource requests for different users are cached separately, thus generating full traffic to our origin. The point is - CloudFront should take into account cookie name and expiration date, but ignore its content.

Is there any way to accomplish this?

Upvotes: 1

Views: 3483

Answers (1)

Michael - sqlbot
Michael - sqlbot

Reputation: 179414

No, there isn't. Here's why:

When a response is stored by a web cache, the corresponding request is also stored. The cache must not consider two requests to be identical unless they are indeed identical requests.

Two requests cannot be considered identical unless they are, in fact, identical in every way, when what was sent to the origin is taken into account.

Prior to sending a request to the origin, CloudFront strips the incoming request of anything that it will not be forwarding -- headers, cookies, query strings -- and everything that remains... that is, everything that will be sent to the origin... is what will be compared, on subsequent requests.

The reason for this is that a cache is prohibited from returning an invalid response, and unless an identical request is sent to the origin, there is no way for a cache to know whether the response will also be identical; therefore, a request that results in something different being sent to the origin server will never receive a cached response that the origin returned for what was (by definition) not the same request.

This is why CloudFront allows selective whitelisting of headers as well as cookies: so that you can prune what actually gets forwarded down to only what the origin needs to see, in order to respond appropriately. The less you whitelist, the more likely a subsequent request is to actually be identical.

If, for example, you forwarded the User-Agent: header to the origin, the origin server might respond differently based on heuristics applied to the user agent (supplying different content, say, for IE than for Firefox or Chrome, to accommodate IE's quirks). If your origin needs that information, you have to forward it, and take the penalty that comes with it -- the response will only be served from cache for another user with an identical browser. If you don't need the user agent string, you don't forward it -- for this reason.

Evaluating cookies by name only would clearly be at odds with this logic. The cookie value is different, because the user identity is different, and the origin should reasonably be expected to respond differently. (Also, note that when the browser presents a cookie, it doesn't present the expiration time. That information is only present when the server sets a cookie.)

If you need to provide authenticated access to cached objects, you'll need to use one of CloudFront's built-in auth mechanisms, rather than passing the authentication/authorization through to the origin using cookies.

Upvotes: 2

Related Questions