RFC 4559

SPNEGO-based Kerberos and NTLM HTTP Authentication in Microsoft Windows

πŸ“… published June 2006, from ietf

RFC 4559 πŸ’– SPNEGO-based Kerberos and NTLM HTTP Authentication in Microsoft Windows

Okay bestie, paperwork first πŸ“‹βœ¨ This is RFC 4559, written by K. Jaganathan, L. Zhu, and J. Brezak from Microsoft Corporation, dated June 2006. It's Informational, so it's sharing how things work for the Internet community rather than setting an Internet standard. The title block doesn't list any RFC it obsoletes or updates, so no drama there 🌸


Status of This Memo ✨

This memo gives info to the Internet community πŸ’… It does not specify an Internet standard of any kind, and distribution of it is unlimited.

Copyright (C) The Internet Society (2006).

Abstract πŸ¦‹

So this doc explains how Microsoft Internet Explorer (MSIE) and Internet Information Services (IIS), which come in Microsoft Windows 2000, use Kerberos to beef up security for web transactions πŸ” The HTTP auth-scheme called "negotiate" is defined right here. When the negotiation ends up picking Kerberos, you get authentication and, optionally, impersonation. That's when the IIS server takes on the windows identity of the principal that got authenticated πŸ‘‘

This doc also explains how HTTP authentication uses the Simple and Protected GSS-API Negotiation mechanism. Details of Simple And Protected Negotiate (SPNEGO) implementation aren't covered here, though πŸ™ˆ

Table of Contents πŸ“š

1. Introduction ....................................................2
2. Conventions Used in This Document ...............................2
3. Access Authentication ...........................................2
   3.1. Reliance on the HTTP/1.1 Specification .....................2
4. HTTP Negotiate Authentication Scheme ............................2
   4.1. The WWW-Authenticate Response Header .......................2
5. Negotiate Operation Example .....................................4
6. Security Considerations .........................................5
7. Normative References ............................................6

1. Introduction 🌈

Microsoft added support for Kerberos authentication in Microsoft Internet Explorer (MSIE) and Internet Information Services (IIS), alongside other mechanisms. That means you get the perks of the Kerberos v5 protocol for web apps, which is seriously iconic 😭

Kerberos support is built on top of mechanisms that already existed, like SPNEGO Simple And Protected Negotiate (SPNEGO) [RFC4178] and the Generic Security Services Application Program Interface(GSSAPI). Pure building blocks, no notes 🧱

2. Conventions Used in This Document πŸ“

Here's the vibe check on the capitalised words. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in [RFC2119]. Those ones are special πŸ’œ

3. Access Authentication πŸ”‘

3.1. Reliance on the HTTP/1.1 Specification 🧩

This spec is a companion to the HTTP/1.1 specification [RFC2616], and it builds on the authentication mechanisms defined in [RFC2617]. It uses the augmented BNF section of that document (2.1), and it relies on both the non-terminals defined in that document and other aspects of the HTTP/1.1 specification. It's all connected, bestie 🫢

4. HTTP Negotiate Authentication Scheme πŸŽ€

Kerberos gets wrapped up in an HTTP auth-scheme called "Negotiate". The auth-params use data formats defined for the GSS-API [RFC2743]. Specifically, they follow the formats set for the SPNEGO [RFC4178] and Kerberos [RFC4121] mechanisms for GSSAPI. The "Negotiate" auth-scheme calls for SPNEGO GSSAPI tokens, which the specific mechanism type spells out πŸ’…

Right now, this protocol only works with SPNEGO using the Kerberos and Microsoft (NT Lan Manager) NTLM protocols. That's the current implementation, so it's not everything yet 🌸

4.1. The WWW-Authenticate Response Header πŸ¦‹

If the server gets a request for an access-protected object, and no acceptable Authorization header has been sent, it responds with a "401 Unauthorized" status code and a "WWW-Authenticate:" header, following the framework in [RFC2616]. The initial WWW-Authenticate header won't carry any gssapi-data.

The negotiate scheme works like this:

challenge       = "Negotiate" auth-data
auth-data       = 1#( [gssapi-data] )

Here's what the directives above mean πŸ”

gssapi-data

If gss_accept_security_context returns a token for the client, this directive holds the base64 encoding of an initialContextToken, as defined in [RFC2743]. It's not in the server's initial response.

A 200 status response can also carry a "WWW-Authenticate" response header with the final leg of an authentication. In that case, gssapi-data will be present. Before using the response contents, the gssapi-data should be processed by gss_init_security_context to figure out the state of the security context. If that function says success, the app can use the response. Otherwise, the app should take an appropriate action based on the authentication status πŸ‘€

For example, the authentication could fail on the final leg if mutual authentication was requested and the server couldn't prove its identity. In that case, the returned results are suspect πŸ™ˆ It's not always possible to mutually authenticate the server before the HTTP operation. POST methods are in this category.

When the Kerberos Version 5 GSSAPI mechanism [RFC4121] is in use, the HTTP server uses a principal name of the form "HTTP/hostname" ✨

4.2. The Authorization Request Header πŸ’Œ

When the client gets a response from the server with a "WWW-Authenticate" header, it's expected to retry the HTTP request, sending an HTTP "Authorization" header line. This follows the framework in [RFC2616] and works like this:

credentials             = "Negotiate" auth-data2
auth-data2              = 1#( gssapi-data )

gssapi-data This directive holds the base64 encoding of an InitialContextToken, as defined in [RFC2743].

Any returned code other than a success 2xx code means there's an authentication error 😭 If the server sends back a 401 with a "WWW-Authenticate" header containing "Negotiate" and gssapi-data, it's a continuation of the authentication request, so keep going πŸ”

A client can start a connection to the server with an "Authorization" header that has the initial token for the server. This skips the initial 401 error from the server, which is handy when the client already knows the server will accept the Negotiate HTTP authentication type ⚑

5. Negotiate Operation Example 🎬

The client asks the server for an access-protected document with a GET request. The URI of the document is "http://www.nowhere.org/dir/index.html".

C: GET dir/index.html

The first time the client asks for the document, there's no Authorization header, so the server responds with:

S: HTTP/1.1 401 Unauthorized
S: WWW-Authenticate: Negotiate

The client gets the user credentials using the SPNEGO GSSAPI mechanism type, then identifies and generates a GSSAPI message to send to the server in a new request, including this Authorization header:

C: GET dir/index.html
C: Authorization: Negotiate a87421000492aa874209af8bc028

The server decodes the gssapi-data and passes it to the SPNEGO GSSAPI mechanism in the gss_accept_security_context function. If the context isn't complete, the server responds with a 401 status code and a WWW-Authenticate header containing the gssapi-data:

S: HTTP/1.1 401 Unauthorized
S: WWW-Authenticate: Negotiate 749efa7b23409c20b92356

The client decodes the gssapi-data, passes it into Gss_Init_security_context, and sends the new gssapi-data back to the server:

C: GET dir/index.html
C: Authorization: Negotiate 89a8742aa8729a8b028

This back-and-forth can keep going until the security context is complete πŸ”„ When the return value from gss_accept_security_context says the security context is complete, it may supply final authentication data to send back to the client. If the server has more gssapi data to send to complete the context, it gets carried in a WWW-Authenticate header on the final response that holds the HTTP body:

S: HTTP/1.1 200 Success
S: WWW-Authenticate: Negotiate ade0234568a4209af8bc0280289eca

The client decodes the gssapi-data and gives it to gss_init_security_context, using the context for this server. If the status from that final gss_init_security_context call is successful, the app can use the response πŸŽ‰

6. Security Considerations 🚨

Okay, this section is serious, so read it carefully, bestie πŸ’€

The SPNEGO HTTP authentication facility is only used to authenticate a user to a server. It gives you no way to protect the HTTP headers or data, including the Authorization and WWW-Authenticate headers that power this mechanism 😬

Other mechanisms like TLS can provide confidentiality. Hashes of the TLS certificates can be used as channel bindings to secure the channel. In that case, clients would need to enforce that the channel binding information is valid. Also, Kerb-TLS [RFC2712] could provide both authentication and confidentiality, but that needs a change to the TLS provider πŸ”

This mechanism is not used for HTTP authentication to HTTP proxies. Not for proxies, got it? πŸ™…β€β™€οΈ

If an HTTP proxy sits between the client and server, it must take care not to share authenticated connections between different authenticated clients to the same server. If that isn't honored, the server can easily lose track of security context associations 🫠 A proxy that correctly honors client-to-server authentication integrity will supply the "Proxy-support: Session-Based-Authentication" HTTP header to the client in HTTP responses from the proxy. The client MUST NOT utilize the SPNEGO HTTP authentication mechanism through a proxy unless the proxy supplies this header with the "401 Unauthorized" response from the server. That's a hard no without it, periodt πŸ›‘

When using the SPNEGO HTTP authentication facility with client-supplied data such as PUT and POST, the authentication should be complete between the client and server before sending the user data. The return status from gss_init_security_context will indicate whether the security context is complete. At that point, the data can be sent to the server πŸ’–


Part 1 wraps here, bestie, and part 2 is coming with the rest πŸ¦‹βœ¨

7. Normative References ✨

okay bestie, this is the reading list πŸ“š these are the docs the spec leans on, so they're the foundation, not optional vibes πŸ’…

  • [RFC2743] Linn, J., "Generic Security Service Application Program Interface Version 2", 2, Update 1", 2743, January 2000.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC4178] Zhu, L., Leach, P., Jaganathan, K., and W. Ingersoll, "The Simple and Protected GSS-API Generic Security Service Application Program Interface (GSS-API) Negotiation Mechanism", 4178, October 2005.
  • [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., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., and L. Stewart, "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, June 1999.
  • [RFC2712] Medvinsky, A. and M. Hur, "Addition of Kerberos Cipher Suites to Transport Layer Security (TLS)", RFC 2712, October 1999.
  • [RFC4121] Zhu, L., Jaganathan, K., and S. Hartman, "The Kerberos Version 5 Generic Security Service Application Program Interface (GSS-API) Mechanism: Version 2", RFC 4121, July 2005.

Authors' Addresses πŸ¦‹

meet the squad behind this spec 🫢 all three are at Microsoft Corporation, One Microsoft Way, Redmond, WA 98052, US

Karthik Jaganathan
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
US

EMail: karthikj@microsoft.com


Larry Zhu
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
US

EMail: lzhu@microsoft.com


John Brezak
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
US

EMail: jbrezak@microsoft.com

Copyright (C) The Internet Society (2006). πŸ’–

this doc is subject to the rights, licenses and restrictions in BCP 78 and at www.rfc-editor.org/copyright.html. except as set forth there, the authors keep all their rights πŸŽ€

now the legal part, and it's serious. the doc is provided "AS IS". the contributor, the organization they represent or are sponsored by (if any), the Internet Society, and the Internet Engineering Task Force all disclaim every warranty, express or implied, including (but not limited to) any warranty that using the info here won't infringe any rights, and any implied warranties of merchantability or fitness for a particular purpose πŸ’€

Intellectual Property πŸ”₯

The IETF takes no position on whether any Intellectual Property Rights (or other rights) that might be claimed to cover the tech in this doc are valid or in scope, or whether licenses for them are available. it also doesn't claim to have done any independent search for such rights πŸ•΅οΈβ€β™€οΈ info on how rights work for RFCs is in BCP 78 and BCP 79.

copies of IPR disclosures sent to the IETF Secretariat, any assurances of licenses, and the outcome of any attempt to get a general license or permission for implementers or users are available from the IETF's online IPR repository at http://www.ietf.org/ipr 🌸

the IETF also invites anyone to flag copyrights, patents, patent applications, or other proprietary rights that might cover tech needed to implement this standard. send that to the IETF at ietf-ipr@ietf.org πŸ“¬βœ¨

Acknowledgement 🧚

funding for the RFC Editor function comes from the IETF Administrative Support Activity (IASA) πŸ’œ and that's the whole RFC, bestie! πŸŽ€πŸ‘‘

πŸ“¦ where this page comes from