diff --git a/app/vmauth/auth_config.go b/app/vmauth/auth_config.go index 4abe6793b..69ec0b1a9 100644 --- a/app/vmauth/auth_config.go +++ b/app/vmauth/auth_config.go @@ -60,6 +60,7 @@ type UserInfo struct { Name string `yaml:"name,omitempty"` BearerToken string `yaml:"bearer_token,omitempty"` + AuthToken string `yaml:"auth_token,omitempty"` Username string `yaml:"username,omitempty"` Password string `yaml:"password,omitempty"` @@ -689,6 +690,9 @@ func parseAuthConfig(data []byte) (*AuthConfig, error) { if ui.BearerToken != "" { return nil, fmt.Errorf("field bearer_token can't be specified for unauthorized_user section") } + if ui.AuthToken != "" { + return nil, fmt.Errorf("field auth_token can't be specified for unauthorized_user section") + } if ui.Name != "" { return nil, fmt.Errorf("field name can't be specified for unauthorized_user section") } @@ -729,7 +733,7 @@ func parseAuthConfigUsers(ac *AuthConfig) (map[string]*UserInfo, error) { byAuthToken := make(map[string]*UserInfo, len(uis)) for i := range uis { ui := &uis[i] - ats, err := getAuthTokens(ui.BearerToken, ui.Username, ui.Password) + ats, err := getAuthTokens(ui.AuthToken, ui.BearerToken, ui.Username, ui.Password) if err != nil { return nil, err } @@ -879,10 +883,24 @@ func (ui *UserInfo) name() string { h := xxhash.Sum64([]byte(ui.BearerToken)) return fmt.Sprintf("bearer_token:hash:%016X", h) } + if ui.AuthToken != "" { + h := xxhash.Sum64([]byte(ui.AuthToken)) + return fmt.Sprintf("auth_token:hash:%016X", h) + } return "" } -func getAuthTokens(bearerToken, username, password string) ([]string, error) { +func getAuthTokens(authToken, bearerToken, username, password string) ([]string, error) { + if authToken != "" { + if bearerToken != "" { + return nil, fmt.Errorf("bearer_token cannot be specified if auth_token is set") + } + if username != "" || password != "" { + return nil, fmt.Errorf("username and password cannot be specified if auth_token is set") + } + at := getHTTPAuthToken(authToken) + return []string{at}, nil + } if bearerToken != "" { if username != "" || password != "" { return nil, fmt.Errorf("username and password cannot be specified if bearer_token is set") @@ -899,6 +917,10 @@ func getAuthTokens(bearerToken, username, password string) ([]string, error) { return nil, fmt.Errorf("missing authorization options; bearer_token or username must be set") } +func getHTTPAuthToken(authToken string) string { + return "http_auth:" + authToken +} + func getHTTPAuthBearerToken(bearerToken string) string { return "http_auth:Bearer " + bearerToken } diff --git a/app/vmauth/auth_config_test.go b/app/vmauth/auth_config_test.go index 2c717ad4f..f6ae94ba9 100644 --- a/app/vmauth/auth_config_test.go +++ b/app/vmauth/auth_config_test.go @@ -88,6 +88,22 @@ users: url_prefix: [] `) + // auth_token and username in a single config + f(` +users: +- auth_token: foo + username: bbb + url_prefix: http://foo.bar +`) + + // auth_token and bearer_token in a single config + f(` +users: +- auth_token: foo + bearer_token: bbb + url_prefix: http://foo.bar +`) + // Username and bearer_token in a single config f(` users: @@ -275,8 +291,9 @@ func TestParseAuthConfigSuccess(t *testing.T) { } } - // Single user insecureSkipVerifyTrue := true + + // Single user f(` users: - username: foo @@ -294,6 +311,22 @@ users: }, }) + // Single user with auth_token + f(` +users: +- auth_token: foo + url_prefix: http://aaa:343/bbb + max_concurrent_requests: 5 + tls_insecure_skip_verify: true +`, map[string]*UserInfo{ + getHTTPAuthToken("foo"): { + AuthToken: "foo", + URLPrefix: mustParseURL("http://aaa:343/bbb"), + MaxConcurrentRequests: 5, + TLSInsecureSkipVerify: &insecureSkipVerifyTrue, + }, + }) + // Multiple url_prefix entries insecureSkipVerifyFalse := false f(` diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 832aa80ec..5de9942f4 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -38,7 +38,8 @@ See also [LTS releases](https://docs.victoriametrics.com/lts-releases/). * FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): allow discovering ip addresses for backend instances hidden behind a shared hostname, via `discover_backend_ips: true` option. This allows evenly spreading load among backend instances. See [these docs](https://docs.victoriametrics.com/vmauth/#discovering-backend-ips) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5707). * FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): allow routing incoming requests based on HTTP [query args](https://en.wikipedia.org/wiki/Query_string) via `src_query_args` option at `url_map`. See [these docs](https://docs.victoriametrics.com/vmauth/#generic-http-proxy-for-different-backends) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5878). * FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): allow routing incoming requests based on HTTP request headers via `src_headers` option at `url_map`. See [these docs](https://docs.victoriametrics.com/vmauth/#generic-http-proxy-for-different-backends). -* FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): add ability to read auth tokens from arbitrary HTTP request headers. Previously auth tokens were read only from `Authorization` HTTP request header. See [these docs](https://docs.victoriametrics.com/vmauth/#reading-auth-tokens-from-other-http-headers) for details. +* FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): add ability to read auth tokens from arbitrary HTTP request headers via `-httpAuthHeader` command-line flag. Previously auth tokens were read only from `Authorization` HTTP request header. See [these docs](https://docs.victoriametrics.com/vmauth/#reading-auth-tokens-from-other-http-headers) for details. +* FEATURE: [vmauth](https://docs.victoriametrics.com/vmauth/): add ability to authorize by opaque HTTP request header value via `auth_token` option in [-auth.config](https://docs.victoriametrics.com/vmauth/#auth-config). * FEATURE: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation/): reduce memory usage by up to 5x when aggregating over big number of unique [time series](https://docs.victoriametrics.com/keyconcepts/#time-series). The memory usage reduction is most visible when [stream deduplication](https://docs.victoriametrics.com/stream-aggregation/#deduplication) is enabled. * FEATURE: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation/): allow using `-streamAggr.dedupInterval` and `-remoteWrite.streamAggr.dedupInterval` command-line flags without the need to specify `-streamAggr.config` and `-remoteWrite.streamAggr.config`. See [these docs](https://docs.victoriametrics.com/stream-aggregation/#deduplication). * FEATURE: [stream aggregation](https://docs.victoriametrics.com/stream-aggregation/): add `-streamAggr.dropInputLabels` command-line flag, which can be used for dropping the listed labels from input samples before applying stream [de-duplication](https://docs.victoriametrics.com/stream-aggregation/#deduplication) and aggregation. This is faster and easier to use alternative to [input_relabel_configs](https://docs.victoriametrics.com/stream-aggregation/#relabeling). See [these docs](https://docs.victoriametrics.com/stream-aggregation/#dropping-unneeded-labels). diff --git a/docs/vmauth.md b/docs/vmauth.md index 50ad776a9..3f7158f41 100644 --- a/docs/vmauth.md +++ b/docs/vmauth.md @@ -666,6 +666,11 @@ users: - bearer_token: "XXXX" url_prefix: "http://localhost:8428" + # Requests with the 'Authorization: Foo XXXX' header are proxied to http://localhosT:8428 . + # For example, http://vmauth:8427/api/v1/query is proxied to http://localhost:8428/api/v1/query +- auth_token: "Foo XXXX" + url_prefix: "http://localhost:8428" + # Requests with the 'Authorization: Bearer YYY' header are proxied to http://localhost:8428 , # The `X-Scope-OrgID: foobar` http header is added to every proxied request. # The `X-Server-Hostname` http header is removed from the proxied response.