This document describes a general purpose, pluggable, authentication protocol that can be used by M2M clients to authenticate themselves with a compliant server. After successfully authenticating, the client receives an auth token from the server that can be used to gain access to protected resources.
Introduction
The high-level steps to obtain an auth token are:
Hello Handshake
The client sends a hello message to the server identifying the user who wants to authenticate.
The server responds indicating which authentication mechanisms are supported for that user.
Authentication Exchange
The client picks an authentication mechanism and exchanges messages with the server to authenticate.
If the server authenticates the user, it sends the client an auth token it can use to access protected resources.
The client uses the auth token for all future requests to the server.
The rest of this document describes this process in more detail. We also define a standard set of authentication mechanisms and define how the authentication exchange should work for each mechanism.
HTTP1/1. Authentication
This specification is based on the authentication framework presented in "HTTP/1.1: Authentication" RFC7235. We build on this framework by adding an explicit method for establishing what the supported authentication mechanisms are for a particular user. There are also a few restrictions on that specification that compliant clients and servers must adhere to.
Syntax restrictions
In order to make the parsing of authentication headers as easy as possible for clients and servers, we place the following restrictions on the syntax rules for encoding authentication headers.
"auth-param" syntax MUST NOT use "quoted-string" syntax
Auth schemes ("challenge" and "credentials") MUST NOT use "token68"
The following modified syntax rules MUST be used for constructing authentication headers:
Essentitially, we only allow the "token" syntax in any production rule. If a raw auth-param value is not a valid token, then the value SHOULD be encoded using base64url with no paddingRFC4648
Authentication Protocol
The authentication protocol is a series of HTTP requests to the server. The URI to use for authentication is determined by the server. If a client attempts to access a protected resource without a valid auth token, the server should return a 401 challenge.
All messages to the server MUST use the HTTP GET method.
The server MAY include a "handshakeToken" parameter in its responses to the client. The handshakeToken is used by the server to maintain state between requests. If the server includes this parameter, the client MUST include it on its next request to the server. Its value is opaque and server-defined.
Hello
The first step in the authentication protocol is for the client to initiate the authentication handshake with a hello message. The Authorization header is used to supply the username of the client using the HELLO auth scheme. The username parameter is the base64url encoding of the UTF8-encoded username.
The server responds to a hello request with a 401 (Unauthorized) response. The response uses the WWW-Authenticate header to indicate to the client what authentication mechanisms are supported for the supplied username. If multiple authentication mechanisms are supported, the server SHOULD specify them in order of most preferred to least preferred.
If the server does not recognize the username, it SHOULD still return a 401 (unauthorized) with at least one valid authentication mechanism. During the authentication exchange, the user will not validate and at that point a 403 (Forbidden) status code should be sent. This approach makes it more difficult for a potential attacker to determine valid usernames for the system.
In this example, the username is “user", and the server responds indicating that user may authenticate with SCRAM. A "handshakeToken" is included in the response, so the client must included it on its next request.
At this point the client may choose which authentication mechanism it wants to use for authentication. The rest of the handshake is defined based on this choice. The authentication mechanism MUST be defined in this document to be compliant with this specification.
During the authentication exchange, if the client fails to authenticate then the server MUST respond with a 403 (Forbidden) status code.
Once the server has authenticated the client, the last message it sends to the client MUST be a 200 (Ok). The response MUST use the Authentication-Info RFC7615 header to return an “authToken" that the client uses for future requests to protected resources. The parameter MUST be named authToken. Its value is server-defined and opaque as far as this specification is concerned.
The server MAY also return additional parameters in the header. For example, the last server message for SCRAM authentication contains information the client can use to verify the server.
The client is now authenticated with the server and may access protected resources. All requests for protected resources MUST use the Authorization header to pass the "authToken" to the server. The “Bearer" auth scheme MUST be used to pass the token.
C: GET /some/resource HTTP/1.1
Host: server.example.com
Authorization: BEARER authToken=xxyyzz
[...]
Authentication Mechanisms
This section lists the supported auth schemes. A compliant client and server must implement the authentication exchange for a particular auth scheme as defined in this document.
All clients and servers MUST support SCRAM with SHA-256 as the hash funtion.
The following auth parameters are valid for all authentication schemes:
The server MAY include a handshakeToken parameter in its responses to the client. The handshakeToken is used by the server to maintain state between requests during the authentication exchange. If the server includes this parameter, the client MUST include it on its next request to the server. Its value is opaque and server-defined.
SCRAM
The SCRAM auth scheme SHALL be used to authenticate the client using the Salted Challenge Response Authentication Mechanism (SCRAM). SCRAM is defined in RFC5802.
The cryptographic hash function to use is specified as an auth parameter in the server's response to the hello message. Regardless of which hash function is used, the authentication exchange messages are the same, and defined below. The approach used in this document is based on the experimental "Salted Challenged Response HTTP Authentication Mechanism" RFC7804.
In this example, the username is “user" and the password is “pencil". SHA-256 is used as the cryptographic hash function.
Hello
Note: Header lines have been split to ease readability. All base64url encodings are without padding.
The client sends a hello message indicating identifying itself as "user".
C: GET /haystack/about HTTP/1.1
Host: server.example.com
Authorization: HELLO username=dXNlcg
The server responds indicating that the client should authentication with SCRAM.
The "hash" attribute MUST be included to specify the cryptographic hash function. The following are supported values for the hash attribute:
SHA-256
SHA-512
The server included a "handshakeToken", so the client MUST include it on its next request.
The client initiates the authentication exchange. The Authorization header specifies SCRAM as the authentication scheme. The following attributes are specified:
The "handshakeToken" is included since the server included one its response to the hello message.
The “data" attribute contains the base64url-encoded “client-first-message".
C: GET /haystack/about HTTP/1.1
Host: server.example.com
Authorization: SCRAM handshakeToken=aabbcc
data=biwsbj11c2VyLHI9ck9wck5HZndFYmVSV2diTkVrcU8K
The server responds to the client with the following attributes:
A “handshakeToken" is specified. So the client MUST include this parameter on its next request to the server.
The "hash" attribute MUST be specified to indicate which hash function is being used.
The “data" attribute contains the base64url-encoded “server-first-message".
The final server message indicates that the user is authenticated. Since this is the final server message, it responds with a 200 (Ok) as described in the Auth Token section. The following attributes are specified:
The server includes the required "authToken"
The "hash" attribute MUST be specified to indicate what hash function to use when validating the server key.
The “data" attribute contains the base64url-encoded "server-final-message" The client SHOULD authenticate the server by checking the validity of the server final message.
S: HTTP/1.1 200 Ok
Authentication-Info: authToken=AuthenticatedTokenXXYYZZ, hash=SHA-256
data=dj02cnJpVFJCaTIzV3BSUi93dHVwK21NaFVaVW4vZEI1bkxUSlJzamw5NUc0PQo
References
RFC4648: The Base16, Base32, Base64 Data Encodings
clarify handshakeToken may be included on response to Hello
Matthew GianniniThu 14 Apr 2016
Hello all. The above post contains a draft proposal for standardizing haystack authentication over HTTP. It is actually a more general approach that could work for other types of servers, since it does not require use of haystack data structures to do the authentication, nor does it depend on the haystack REST api.
Here is a link to a PDF version of the proposal. Unfortunately, the in-document linking does not work, but it might ease the reading a bit.
Matthew GianniniTue 3 May 2016
I just updated the original post with a version 0.2.0 of the draft. There are a few notable changes in this update.
First, the SCRAM auth mechanism has been updated so that the name of the scheme is just SCRAM, and the hash function is now sent as an auth-param.
Also, we have further restricted the allowable syntax for use with the various authentication headers (WWW-Authenticate, Authorization, Authorization-Info). We were concerned that the complexity of parsing the full grammar for those headers would prohibit adoption or implementation of the proposal. These restrictions should make it much simpler to write client and server libraries.
Change Log
0.2.0 (27 Apr 2016)
Do not require /auth to the be authentication URI
Only allow token syntax in authentication headers
Update SCRAM to parameterize the hash function
clarify handshakeToken may be included on response to Hello
Matthew Giannini Thu 14 Apr 2016
Abstract
This document describes a general purpose, pluggable, authentication protocol that can be used by M2M clients to authenticate themselves with a compliant server. After successfully authenticating, the client receives an auth token from the server that can be used to gain access to protected resources.
Introduction
The high-level steps to obtain an auth token are:
The rest of this document describes this process in more detail. We also define a standard set of authentication mechanisms and define how the authentication exchange should work for each mechanism.
HTTP1/1. Authentication
This specification is based on the authentication framework presented in "HTTP/1.1: Authentication" RFC7235. We build on this framework by adding an explicit method for establishing what the supported authentication mechanisms are for a particular user. There are also a few restrictions on that specification that compliant clients and servers must adhere to.
Syntax restrictions
In order to make the parsing of authentication headers as easy as possible for clients and servers, we place the following restrictions on the syntax rules for encoding authentication headers.
The following modified syntax rules MUST be used for constructing authentication headers:
Essentitially, we only allow the "token" syntax in any production rule. If a raw auth-param value is not a valid token, then the value SHOULD be encoded using
base64url
with no padding RFC4648Authentication Protocol
The authentication protocol is a series of HTTP requests to the server. The URI to use for authentication is determined by the server. If a client attempts to access a protected resource without a valid auth token, the server should return a 401 challenge.
All messages to the server MUST use the HTTP GET method.
The server MAY include a "handshakeToken" parameter in its responses to the client. The handshakeToken is used by the server to maintain state between requests. If the server includes this parameter, the client MUST include it on its next request to the server. Its value is opaque and server-defined.
Hello
The first step in the authentication protocol is for the client to initiate the authentication handshake with a hello message. The Authorization header is used to supply the username of the client using the HELLO auth scheme. The username parameter is the base64url encoding of the UTF8-encoded username.
The server responds to a hello request with a 401 (Unauthorized) response. The response uses the WWW-Authenticate header to indicate to the client what authentication mechanisms are supported for the supplied username. If multiple authentication mechanisms are supported, the server SHOULD specify them in order of most preferred to least preferred.
If the server does not recognize the username, it SHOULD still return a 401 (unauthorized) with at least one valid authentication mechanism. During the authentication exchange, the user will not validate and at that point a 403 (Forbidden) status code should be sent. This approach makes it more difficult for a potential attacker to determine valid usernames for the system.
In this example, the username is “user", and the server responds indicating that user may authenticate with SCRAM. A "handshakeToken" is included in the response, so the client must included it on its next request.
Authentication Exchange
At this point the client may choose which authentication mechanism it wants to use for authentication. The rest of the handshake is defined based on this choice. The authentication mechanism MUST be defined in this document to be compliant with this specification.
During the authentication exchange, if the client fails to authenticate then the server MUST respond with a 403 (Forbidden) status code.
See the Authentication Mechanisms section for details on the supported mechanisms.
Auth Token
Once the server has authenticated the client, the last message it sends to the client MUST be a 200 (Ok). The response MUST use the Authentication-Info RFC7615 header to return an “authToken" that the client uses for future requests to protected resources. The parameter MUST be named
authToken
. Its value is server-defined and opaque as far as this specification is concerned.The server MAY also return additional parameters in the header. For example, the last server message for SCRAM authentication contains information the client can use to verify the server.
The client is now authenticated with the server and may access protected resources. All requests for protected resources MUST use the Authorization header to pass the "authToken" to the server. The “Bearer" auth scheme MUST be used to pass the token.
Authentication Mechanisms
This section lists the supported auth schemes. A compliant client and server must implement the authentication exchange for a particular auth scheme as defined in this document.
All clients and servers MUST support SCRAM with SHA-256 as the hash funtion.
The following auth parameters are valid for all authentication schemes:
handshakeToken
parameter in its responses to the client. The handshakeToken is used by the server to maintain state between requests during the authentication exchange. If the server includes this parameter, the client MUST include it on its next request to the server. Its value is opaque and server-defined.SCRAM
The
SCRAM
auth scheme SHALL be used to authenticate the client using the Salted Challenge Response Authentication Mechanism (SCRAM). SCRAM is defined in RFC5802.The cryptographic hash function to use is specified as an auth parameter in the server's response to the hello message. Regardless of which hash function is used, the authentication exchange messages are the same, and defined below. The approach used in this document is based on the experimental "Salted Challenged Response HTTP Authentication Mechanism" RFC7804.
In this example, the username is “user" and the password is “pencil". SHA-256 is used as the cryptographic hash function.
Hello
Note: Header lines have been split to ease readability. All base64url encodings are without padding.
The client sends a hello message indicating identifying itself as "user".
The server responds indicating that the client should authentication with SCRAM.
Authentication Exchange
The client initiates the authentication exchange. The Authorization header specifies SCRAM as the authentication scheme. The following attributes are specified:
The server responds to the client with the following attributes:
The client continues the authentication exchange with another GET to /haystack/about. The following attributes are specified:
The final server message indicates that the user is authenticated. Since this is the final server message, it responds with a 200 (Ok) as described in the Auth Token section. The following attributes are specified:
References
RFC4648: The Base16, Base32, Base64 Data Encodings
RFC5802: Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanism
RFC7235: Hypertext Transfer Protocol (HTTP/1.1) : Authentication
RFC7615: HTTP Authentication-Info and Proxy-Authentication-Info Response Header Fields
RFC7804: Salted Challenge Response HTTP Authentication Mechanism
Change Log
0.2.0 (27 Apr 2016)
Matthew Giannini Thu 14 Apr 2016
Hello all. The above post contains a draft proposal for standardizing haystack authentication over HTTP. It is actually a more general approach that could work for other types of servers, since it does not require use of haystack data structures to do the authentication, nor does it depend on the haystack REST api.
Here is a link to a PDF version of the proposal. Unfortunately, the in-document linking does not work, but it might ease the reading a bit.
Matthew Giannini Tue 3 May 2016
I just updated the original post with a version 0.2.0 of the draft. There are a few notable changes in this update.
First, the SCRAM auth mechanism has been updated so that the name of the scheme is just
SCRAM
, and the hash function is now sent as anauth-param
.Also, we have further restricted the allowable syntax for use with the various authentication headers (WWW-Authenticate, Authorization, Authorization-Info). We were concerned that the complexity of parsing the full grammar for those headers would prohibit adoption or implementation of the proposal. These restrictions should make it much simpler to write client and server libraries.
Change Log
0.2.0 (27 Apr 2016)
Here is a link to a PDF version of the proposal.