mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-30 15:22:07 +00:00
app/vmauth: small code cleanup for working with auth tokens
This commit is contained in:
parent
5582a24ecf
commit
9c1331a38a
2 changed files with 34 additions and 40 deletions
|
@ -50,10 +50,12 @@ type AuthConfig struct {
|
||||||
|
|
||||||
// UserInfo is user information read from authConfigPath
|
// UserInfo is user information read from authConfigPath
|
||||||
type UserInfo struct {
|
type UserInfo struct {
|
||||||
Name string `yaml:"name,omitempty"`
|
Name string `yaml:"name,omitempty"`
|
||||||
BearerToken string `yaml:"bearer_token,omitempty"`
|
|
||||||
Username string `yaml:"username,omitempty"`
|
BearerToken string `yaml:"bearer_token,omitempty"`
|
||||||
Password string `yaml:"password,omitempty"`
|
Username string `yaml:"username,omitempty"`
|
||||||
|
Password string `yaml:"password,omitempty"`
|
||||||
|
|
||||||
URLPrefix *URLPrefix `yaml:"url_prefix,omitempty"`
|
URLPrefix *URLPrefix `yaml:"url_prefix,omitempty"`
|
||||||
URLMaps []URLMap `yaml:"url_map,omitempty"`
|
URLMaps []URLMap `yaml:"url_map,omitempty"`
|
||||||
HeadersConf HeadersConf `yaml:",inline"`
|
HeadersConf HeadersConf `yaml:",inline"`
|
||||||
|
@ -582,17 +584,9 @@ func parseAuthConfigUsers(ac *AuthConfig) (map[string]*UserInfo, error) {
|
||||||
byAuthToken := make(map[string]*UserInfo, len(uis))
|
byAuthToken := make(map[string]*UserInfo, len(uis))
|
||||||
for i := range uis {
|
for i := range uis {
|
||||||
ui := &uis[i]
|
ui := &uis[i]
|
||||||
if ui.Username != "" && ui.Password == "" {
|
ats, err := getAuthTokens(ui.BearerToken, ui.Username, ui.Password)
|
||||||
// Do not allow setting username without password if there are other auth configs exist.
|
if err != nil {
|
||||||
// This should prevent from typical mis-configuration when access by username without password
|
return nil, err
|
||||||
// remains open if other authorization schemes are defined.
|
|
||||||
if ui.BearerToken != "" {
|
|
||||||
return nil, fmt.Errorf("bearer_token=%q and username=%q cannot be set simultaneously", ui.BearerToken, ui.Username)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ats := getAuthTokens(ui.BearerToken, ui.Username, ui.Password)
|
|
||||||
if len(ats) == 0 {
|
|
||||||
return nil, fmt.Errorf("one of bearer_token, username or mtls must be set")
|
|
||||||
}
|
}
|
||||||
for _, at := range ats {
|
for _, at := range ats {
|
||||||
if uiOld := byAuthToken[at]; uiOld != nil {
|
if uiOld := byAuthToken[at]; uiOld != nil {
|
||||||
|
@ -600,15 +594,10 @@ func parseAuthConfigUsers(ac *AuthConfig) (map[string]*UserInfo, error) {
|
||||||
at, ui.Username, ui.Name, uiOld.Username, uiOld.Name)
|
at, ui.Username, ui.Name, uiOld.Username, uiOld.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ui.initURLs(); err != nil {
|
if err := ui.initURLs(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui.BearerToken != "" && ui.Password != "" {
|
|
||||||
return nil, fmt.Errorf("password shouldn't be set for bearer_token %q", ui.BearerToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
metricLabels, err := ui.getMetricLabels()
|
metricLabels, err := ui.getMetricLabels()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse metric_labels: %w", err)
|
return nil, fmt.Errorf("cannot parse metric_labels: %w", err)
|
||||||
|
@ -719,7 +708,7 @@ func (ui *UserInfo) initURLs() error {
|
||||||
e.URLPrefix.dropSrcPathPrefixParts = dsp
|
e.URLPrefix.dropSrcPathPrefixParts = dsp
|
||||||
}
|
}
|
||||||
if len(ui.URLMaps) == 0 && ui.URLPrefix == nil {
|
if len(ui.URLMaps) == 0 && ui.URLPrefix == nil {
|
||||||
return fmt.Errorf("missing `url_prefix`")
|
return fmt.Errorf("missing `url_prefix` or `url_map`")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -738,18 +727,21 @@ func (ui *UserInfo) name() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAuthTokens(bearerToken, username, password string) []string {
|
func getAuthTokens(bearerToken, username, password string) ([]string, error) {
|
||||||
var ats []string
|
|
||||||
if bearerToken != "" {
|
if bearerToken != "" {
|
||||||
|
if username != "" || password != "" {
|
||||||
|
return nil, fmt.Errorf("username and password cannot be specified if bearer_token is set")
|
||||||
|
}
|
||||||
// Accept the bearerToken as Basic Auth username with empty password
|
// Accept the bearerToken as Basic Auth username with empty password
|
||||||
at1 := getHTTPAuthBearerToken(bearerToken)
|
at1 := getHTTPAuthBearerToken(bearerToken)
|
||||||
at2 := getHTTPAuthBasicToken(bearerToken, "")
|
at2 := getHTTPAuthBasicToken(bearerToken, "")
|
||||||
ats = append(ats, at1, at2)
|
return []string{at1, at2}, nil
|
||||||
} else if username != "" {
|
|
||||||
at := getHTTPAuthBasicToken(username, password)
|
|
||||||
ats = append(ats, at)
|
|
||||||
}
|
}
|
||||||
return ats
|
if username != "" {
|
||||||
|
at := getHTTPAuthBasicToken(username, password)
|
||||||
|
return []string{at}, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("missing authorization options; bearer_token or username must be set")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHTTPAuthBearerToken(bearerToken string) string {
|
func getHTTPAuthBearerToken(bearerToken string) string {
|
||||||
|
@ -765,17 +757,17 @@ func getHTTPAuthBasicToken(username, password string) string {
|
||||||
func getAuthTokensFromRequest(r *http.Request) []string {
|
func getAuthTokensFromRequest(r *http.Request) []string {
|
||||||
var ats []string
|
var ats []string
|
||||||
|
|
||||||
ah := r.Header.Get("Authorization")
|
// Obtain possible auth tokens from Authorization header
|
||||||
if ah == "" {
|
if ah := r.Header.Get("Authorization"); ah != "" {
|
||||||
return ats
|
if strings.HasPrefix(ah, "Token ") {
|
||||||
|
// Handle InfluxDB's proprietary token authentication scheme as a bearer token authentication
|
||||||
|
// See https://docs.influxdata.com/influxdb/v2.0/api/
|
||||||
|
ah = strings.Replace(ah, "Token", "Bearer", 1)
|
||||||
|
}
|
||||||
|
at := "http_auth:" + ah
|
||||||
|
ats = append(ats, at)
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(ah, "Token ") {
|
|
||||||
// Handle InfluxDB's proprietary token authentication scheme as a bearer token authentication
|
|
||||||
// See https://docs.influxdata.com/influxdb/v2.0/api/
|
|
||||||
ah = strings.Replace(ah, "Token", "Bearer", 1)
|
|
||||||
}
|
|
||||||
at := "http_auth:" + ah
|
|
||||||
ats = append(ats, at)
|
|
||||||
return ats
|
return ats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ func TestParseAuthConfigFailure(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = parseAuthConfigUsers(ac)
|
users, err := parseAuthConfigUsers(ac)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expecting non-nil error")
|
t.Fatalf("expecting non-nil error; got %v", users)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,6 +395,7 @@ users:
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Multiple users with the same name - this should work, since these users have different passwords
|
// Multiple users with the same name - this should work, since these users have different passwords
|
||||||
f(`
|
f(`
|
||||||
users:
|
users:
|
||||||
|
@ -498,6 +499,7 @@ users:
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// With metric_labels
|
// With metric_labels
|
||||||
f(`
|
f(`
|
||||||
users:
|
users:
|
||||||
|
|
Loading…
Reference in a new issue