Merge pull request #1318 from daveadams/f-http-header-token

Allow specifying Consul token in an HTTP request header
This commit is contained in:
Armon Dadgar 2015-10-22 13:33:47 -07:00
commit 6a350d5d19
3 changed files with 37 additions and 3 deletions

View File

@ -463,13 +463,18 @@ func (s *HTTPServer) parseDC(req *http.Request, dc *string) {
} }
} }
// parseToken is used to parse the ?token query param // parseToken is used to parse the ?token query param or the X-Consul-Token header
func (s *HTTPServer) parseToken(req *http.Request, token *string) { func (s *HTTPServer) parseToken(req *http.Request, token *string) {
if other := req.URL.Query().Get("token"); other != "" { if other := req.URL.Query().Get("token"); other != "" {
*token = other *token = other
return return
} }
if other := req.Header.Get("X-Consul-Token"); other != "" {
*token = other
return
}
// Set the AtlasACLToken if SCADA // Set the AtlasACLToken if SCADA
if s.addr == scadaHTTPAddr && s.agent.config.AtlasACLToken != "" { if s.addr == scadaHTTPAddr && s.agent.config.AtlasACLToken != "" {
*token = s.agent.config.AtlasACLToken *token = s.agent.config.AtlasACLToken

View File

@ -473,6 +473,22 @@ func TestACLResolution(t *testing.T) {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
// Request with header token only
reqHeaderToken, err := http.NewRequest("GET",
"/v1/catalog/nodes", nil)
if err != nil {
t.Fatalf("err: %v", err)
}
reqHeaderToken.Header.Add("X-Consul-Token", "bar")
// Request with header and querystring tokens
reqBothTokens, err := http.NewRequest("GET",
"/v1/catalog/nodes?token=baz", nil)
if err != nil {
t.Fatalf("err: %v", err)
}
reqBothTokens.Header.Add("X-Consul-Token", "zap")
httpTest(t, func(srv *HTTPServer) { httpTest(t, func(srv *HTTPServer) {
// Check when no token is set // Check when no token is set
srv.agent.config.ACLToken = "" srv.agent.config.ACLToken = ""
@ -514,6 +530,18 @@ func TestACLResolution(t *testing.T) {
if token != "foo" { if token != "foo" {
t.Fatalf("bad: %s", token) t.Fatalf("bad: %s", token)
} }
// Header token has precedence over agent token
srv.parseToken(reqHeaderToken, &token)
if token != "bar" {
t.Fatalf("bad: %s", token)
}
// Querystring token has precendence over header and agent tokens
srv.parseToken(reqBothTokens, &token)
if token != "baz" {
t.Fatalf("bad: %s", token)
}
}) })
} }

View File

@ -91,5 +91,6 @@ on the query string, formatted JSON will be returned.
Several endpoints in Consul use or require ACL tokens to operate. An agent Several endpoints in Consul use or require ACL tokens to operate. An agent
can be configured to use a default token in requests using the `acl_token` can be configured to use a default token in requests using the `acl_token`
configuration option. However, the token can also be specified per-request configuration option. However, the token can also be specified per-request
by using the `token` query parameter. This will take precedent over the by using the `X-Consul-Token` request header or the `token` querystring
default token. parameter. The request header takes precedence over the default token, and
the querystring parameter takes precedence over everything.