Skip to content

Commit

Permalink
added support for bearer token authentication (#3749)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbluxo authored Jun 9, 2021
1 parent ddbf04f commit 88708d4
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
2 changes: 2 additions & 0 deletions cmd/logcli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ func newQueryClient(app *kingpin.Application) client.Client {
app.Flag("cert", "Path to the client certificate. Can also be set using LOKI_CLIENT_CERT_PATH env var.").Default("").Envar("LOKI_CLIENT_CERT_PATH").StringVar(&client.TLSConfig.CertFile)
app.Flag("key", "Path to the client certificate key. Can also be set using LOKI_CLIENT_KEY_PATH env var.").Default("").Envar("LOKI_CLIENT_KEY_PATH").StringVar(&client.TLSConfig.KeyFile)
app.Flag("org-id", "adds X-Scope-OrgID to API requests for representing tenant ID. Useful for requesting tenant data when bypassing an auth gateway.").Default("").Envar("LOKI_ORG_ID").StringVar(&client.OrgID)
app.Flag("bearer-token", "adds the Authorization header to API requests for authentication purposes. Can also be set using LOKI_BEARER_TOKEN env var.").Default("").Envar("LOKI_BEARER_TOKEN").StringVar(&client.BearerToken)
app.Flag("bearer-token-file", "adds the Authorization header to API requests for authentication purposes. Can also be set using LOKI_BEARER_TOKEN_FILE env var.").Default("").Envar("LOKI_BEARER_TOKEN_FILE").StringVar(&client.BearerTokenFile)

return client
}
Expand Down
2 changes: 1 addition & 1 deletion docs/sources/getting-started/logcli.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ $ export LOKI_ADDR=http://localhost:3100

> Note: If you are running Loki behind a proxy server and you have
> authentication configured, you will also have to pass in LOKI_USERNAME
> and LOKI_PASSWORD accordingly.
> and LOKI_PASSWORD, LOKI_BEARER_TOKEN or LOKI_BEARER_TOKEN_FILE accordingly.
```bash
$ logcli labels job
Expand Down
56 changes: 50 additions & 6 deletions pkg/logcli/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ type Tripperware func(http.RoundTripper) http.RoundTripper

// Client contains fields necessary to query a Loki instance
type DefaultClient struct {
TLSConfig config.TLSConfig
Username string
Password string
Address string
OrgID string
Tripperware Tripperware
TLSConfig config.TLSConfig
Username string
Password string
Address string
OrgID string
Tripperware Tripperware
BearerToken string
BearerTokenFile string
}

// Query uses the /api/v1/query endpoint to execute an instant query
Expand Down Expand Up @@ -181,6 +183,27 @@ func (c *DefaultClient) doRequest(path, query string, quiet bool, out interface{
req.Header.Set("X-Scope-OrgID", c.OrgID)
}

if (c.Username != "" || c.Password != "") && (len(c.BearerToken) > 0 || len(c.BearerTokenFile) > 0) {
return fmt.Errorf("at most one of HTTP basic auth (username/password), bearer-token & bearer-token-file is allowed to be configured")
}

if len(c.BearerToken) > 0 && len(c.BearerTokenFile) > 0 {
return fmt.Errorf("at most one of the options bearer-token & bearer-token-file is allowed to be configured")
}

if c.BearerToken != "" {
req.Header.Set("Authorization", "Bearer "+c.BearerToken)
}

if c.BearerTokenFile != "" {
b, err := ioutil.ReadFile(c.BearerTokenFile)
if err != nil {
return fmt.Errorf("unable to read authorization credentials file %s: %s", c.BearerTokenFile, err)
}
bearerToken := strings.TrimSpace(string(b))
req.Header.Set("Authorization", "Bearer "+bearerToken)
}

// Parse the URL to extract the host
clientConfig := config.HTTPClientConfig{
TLSConfig: c.TLSConfig,
Expand Down Expand Up @@ -237,6 +260,27 @@ func (c *DefaultClient) wsConnect(path, query string, quiet bool) (*websocket.Co
h.Set("X-Scope-OrgID", c.OrgID)
}

if (c.Username != "" || c.Password != "") && (len(c.BearerToken) > 0 || len(c.BearerTokenFile) > 0) {
return nil, fmt.Errorf("at most one of HTTP basic auth (username/password), bearer-token & bearer-token-file is allowed to be configured")
}

if len(c.BearerToken) > 0 && len(c.BearerTokenFile) > 0 {
return nil, fmt.Errorf("at most one of the options bearer-token & bearer-token-file is allowed to be configured")
}

if c.BearerToken != "" {
h.Set("Authorization", "Bearer "+c.BearerToken)
}

if c.BearerTokenFile != "" {
b, err := ioutil.ReadFile(c.BearerTokenFile)
if err != nil {
return nil, fmt.Errorf("unable to read authorization credentials file %s: %s", c.BearerTokenFile, err)
}
bearerToken := strings.TrimSpace(string(b))
h.Set("Authorization", "Bearer "+bearerToken)
}

ws := websocket.Dialer{
TLSClientConfig: tlsConfig,
}
Expand Down

0 comments on commit 88708d4

Please sign in to comment.