|Network Working Group||T. Broyer|
|Internet Draft||January 4, 2009|
|Intended status: Standards Track|
|Expires: July 2009|
Cookie-based HTTP Authentication
This Internet-Draft is submitted to IETF pursuant to, and in full conformance with, the provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as “work in progress”.
The list of current Internet-Drafts can be accessed at <http://www.ietf.org/ietf/1id-abstracts.txt>.
The list of Internet-Draft Shadow Directories can be accessed at <http://www.ietf.org/shadow.html>.
This Internet-Draft will expire in July 2009.
Copyright © 2009 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.
This document specifies an HTTP authentication scheme for use when credentials are validated by an out-of-band mechanism (not defined here) and later communicated to the server through the use of a cookie. Which out-of-band mechanism should be used, and how, is described by the 401 (Unauthorized) response body. It is common practice that this mechanism is an HTML form, sending the user's credentials with the use of an HTTP POST request to a tier URL which will set a cookie in response; though this document doesn't preclude the use of other mechanisms.
Distribution of this document is unlimited. Please send comments to the ietf-http-auth mailing list at [email protected], which may be joined by sending a message with subject "subscribe" to [email protected].
Discussions of the ietf-http-auth mailing list are archived at <http://lists.osafoundation.org/pipermail/ietf-http-auth/>.
XML versions, latest edits and the issues list for this document are available from <http://broyer.info/hg/http-cookie-auth/>.
Authentication on the web can be done either at the Hypertext Transfer Protocol (HTTP) [RFC2616] level with a 401 (Unauthorized) status code, or using SSL certificates. Among other issues already listed in User Agent Authentication Forms [W3C.NOTE-authentform-19990203], the former suffers from a poor user experience while the latter can quickly become expensive. That's why the most common authentication mechanism is based on HyperText Markup Language (HTML) forms [W3C.REC-html401-19991224] and cookies [RFC2965].
However, form-based authentication is almost always implemented with an HTTP redirect to the login form, making it impossible for non-browser user agents to detect a protected resource (this leads to people downloading and saving login forms instead of the protected resource they wanted, web service clients failing with unrecoverable errors, etc.).
User Agent Authentication Forms [W3C.NOTE-authentform-19990203] tried to overcome this with an amendment to HTML forms making them "HTTP-authentication aware".
This document solves the problem the other way around, keeping the mechanism backwards compatible with browsers while making it independant of HTML.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL-NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].
The terminology used here follows and extends that in the HTTP specification [RFC2616].
The "cookie" authentication scheme tries to reconcile the current practice of many web sites and web development frameworks of using HTML forms and cookies to authenticate users, and the Access Authentication Framework described in Section 1.2 of [RFC2617]. The user credentials being passed through cookies, the Authorization and Proxy-Authorization request headers are therefore not used.
The "cookie" authentication scheme cannot be used for proxy authentication (within the value of a Proxy-Authenticate response header) because, as defined in Section 3.5 of [RFC2965]:
Proxies MUST NOT introduce Set-Cookie2 (Cookie) headers of their own in proxy responses (requests).
When the origin server sends a 401 (Unauthorized) response containing a WWW-Authenticate header with a "cookie" authentication scheme, the response body gives instructions on how to create the appropriate cookies, generally by issuing another HTTP request (preferably a POST request) to a distinct URL.
In most current web sites and web applications, the response body would be an HTML document containing a form; when the form is submitted, the server checks the user-provided form-data and upon validation sends the appropriate Set-Cookie2 response header fields within a 303 (See Other) response redirecting back to the protected resource.
The "cookie" authentication scheme is however not limited to such scenarios: the response body could be for example an SVG image with an embedded XForms, or an HTML document with an embedded script that will compute a hash of user-provided data and set the cookie by script before reloading the resource, or some specific entity recognized by the UA, which will authenticate using an out-of-band mechanism and set the appropriate cookie before re-requesting the protected resource. This last scenario might be better solved using another authentication scheme, though this scenario would allow server-side negotiation of the authentication mechanism using content negotiation; instead of the client-side negotiation traditionally used when sending multiple WWW-Authenticate response headers.
Syntax (using the augmented Backus-Naur Form (BNF) defined in Section 2.1 of [RFC2616]):
challenge = "Cookie" cookie-challenge cookie-challenge = 1#( realm | [ form-action ] | cookie-name | [ secure-cookie-name ] | [auth-param] ) form-action = "form-action" "=" <"> URI <"> URI = absolute-URI | ( path-absolute [ "?" query ] ) cookie-name = "cookie-name" "=" token secure-cookie-name = "secure-cookie-name" "=" token path-absolute = <defined in [RFC3986], Section 3.3> quoted-string = <defined in [RFC2616], Section 2.2> query = <defined in [RFC3986], Section 3.4> token = <defined in [RFC2616], Section 2.2>
The meanings of the values of the directives used above are as follows:
The applicability of the cookie(s) (its Domain, Port and Path attributes) defines the protection space.
This memo includes no request to IANA.
However, using cookies for account information requires that some additional measures be taken. Using HTTP Over TLS [RFC2818] or other means of encrypting the conversation is sufficient to mitigate most threats, though it requires that some additional measures be taken, as described in this section.
To mitigate replay attacks (re-use of a sniffed cookie), the value of the cookie used for authentication SHOULD NOT contain the users credentials but rather a key associated with the authentication session, and this key SHOULD be renewed (and expired) frequently.
Sensitive information (such as the user's IBAN on an online store) and sensitive actions (such as confirming an order) SHOULD only happen on a secure channel such as HTTP Over TLS [RFC2818], and protected with a secure cookie (a cookie with the "Secure" bit set) so that it cannot be stolen on a unsecured channel.
This document does not specify how credentials are sent to the "form-action" URL, though care should be taken that those credentials cannot be sniffed. In the case of an HTML form, the "form-action" SHOULD use a secure channel such as HTTP Over TLS [RFC2818].
[rfc.comment.1: TODO: document how secure-cookie-name helps with security by preventing replay-attacks. The cookie must obviously have the Secure attribute set.]
[rfc.comment.2: TODO: add some words about CSRF (and find a normative reference). Mention "logout" as a mean to mitigate CSRF.]
|[RFC2119]||Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.|
|[RFC2616]||Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1”, RFC 2616, June 1999.|
|[RFC2617]||Franks, J., Hallam-Baker, P.M., Hostetler, J.L., Lawrence, S.D., Leach, P.J., Luotonen, A., and L. Stewart, “HTTP Authentication: Basic and Digest Access Authentication”, RFC 2617, June 1999.|
|[RFC2818]||Rescorla, E., “HTTP Over TLS”, RFC 2818, May 2000.|
|[RFC2965]||Kristol, D. M. and L. Montulli, “HTTP State Management Mechanism”, RFC 2965, October 2000.|
|[RFC3986]||Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax”, RFC 3986, January 2005.|
|[W3C.NOTE-authentform-19990203]||Lawrence, S. and P. Leach, “User Agent Authentication Forms”, W3C NOTE NOTE-authentform-19990203, February 1999.|
|[W3C.REC-html401-19991224]||Jacobs, I., Hors, A., and D. Raggett, “HTML 4.01 Specification”, World Wide Web Consortium Recommendation REC-html401-19991224, December 1999, <http://www.w3.org/TR/1999/REC-html401-19991224>.|
Most detail of request and response headers has been omitted. Assume that the user agent has no stored cookies.
GET https://www.example.com/acme/ HTTP/1.1
HTTP/1.1 401 Unauthorized WWW-Authenticate: Cookie realm="Acme" form-action="/acme/login" cookie-name=ACME_TICKET Content-Type: text/html <title>Unauthorized</title> <form action="/acme/login" method=POST> <input type=hidden name=referer value="/acme/"> <p><label>Username: <input name=user></label> <p><label>Password: <input name=pwd type=password></label> <p><button type=submit>Sign in</button> <p><a href="/acme/register">Register for an account</a> </form>
POST https://www.example.com/acme/login HTTP/1.1 Content-Type: application/x-www-form-urlencoded referer=%2Facme%2F&user=Aladdin&password=open%20sesame
HTTP/1.1 303 See Other Location: https://www.example.com/acme/ Set-Cookie2: ACME_TICKET="sdf354s5c1s8e1s"; Version="1"; Path="/acme"; Secure
GET https://www.example.com/acme/ HTTP/1.1 Cookie: $Version="1"; ACME_TICKET="sdf354s5c1s8e1s"; $Path="/acme"
HTTP/1.1 200 OK
GET http://www.example.com/acme/ HTTP/1.1
HTTP/1.1 401 Unauthorized WWW-Authenticate: Cookie realm="Acme" form-action="https://secure.example.com/acme/login" cookie-name=ACME_TICKET secure-cookie-name=ACME_SECURE_TICKET Content-Type: text/html <title>Unauthorized</title> <form action="https://secure.example.com/acme/login" method=POST> <input type=hidden name=referer value="http://www.example.com/acme/"> <p><label>Username: <input name=user></label> <p><label>Password: <input name=pwd type=password></label> <p><button type=submit>Sign in</button> <p><a href="/acme/register">Register for an account</a> </form>
POST https://secure.example.com/acme/login HTTP/1.1 Content-Type: application/x-www-form-urlencoded referer=http%3A%2F%2Fwww.example.com%2Facme%2F&user=Aladdin&password=open%20sesame
HTTP/1.1 303 See Other Location: http://www.example.com/acme/ Set-Cookie2: ACME_TICKET="sdf354s5c1s8e1s"; Version="1"; Path="/acme"; Domain=".example.com" Set-Cookie2: ACME_SECURE_TICKET="drg53d51fd535rg"; Version="1"; Path="/acme"; Domain=".example.com"; Secure
GET http://www.example.com/acme/ HTTP/1.1 Cookie: $Version="1"; ACME_TICKET="sdf354s5c1s8e1s"; $Path="/acme"; $Domain=".example.com"
HTTP/1.1 200 OK
GET https://secure.example.com/acme/ HTTP/1.1 Cookie: $Version="1"; ACME_SECURE_TICKET="drg53d51fd535rg"; $Path="/acme"; $Domain=".example.com"
HTTP/1.1 200 OK
[rfc.comment.3: TODO: using CSRF and server-to-server communication to achieve cross-domain single sign-on between sso.some-co.com and www.some-tm.net.]
Or maybe these should be two distinct examples?
And do not forget the "single-logout" issue.