Add option to strip prefixes upon checking user or acl.
This commit is contained in:
parent
1207622cb2
commit
fa99ba6583
10
README.md
10
README.md
|
@ -405,10 +405,18 @@ The above example will do up to 2 retries (3 calls in total considering the orig
|
|||
|
||||
#### Prefixes
|
||||
|
||||
Though the plugin may have multiple backends enabled, there's a way to specify which backend must be used for a given user: prefixes. When enabled, `prefixes` allow to check if the username contains a predefined prefix in the form prefix_username and use the configured backend for that prefix. Options to enable and set prefixes are the following:
|
||||
Though the plugin may have multiple backends enabled, there's a way to specify which backend must be used for a given user: prefixes.
|
||||
When enabled, `prefixes` allow to check if the username contains a predefined prefix in the form prefix_username and use the configured backend for that prefix.
|
||||
There's also an option to strip the prefix upon checking user or acl,
|
||||
so that if a record for `username` exists on a backend with prefix `prefix`,
|
||||
then both `username` and `prefix_username` would be authenticated/authorized. Notice that the former would
|
||||
need to loop through all the backends since it carries no prefix, while the latter will only be checked by the correct backend.
|
||||
|
||||
Options to enable and set prefixes are the following:
|
||||
|
||||
```
|
||||
auth_opt_check_prefix true
|
||||
auth_opt_strip_prefix true
|
||||
auth_opt_prefixes filesprefix, pgprefix, jwtprefix
|
||||
```
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ type Backends struct {
|
|||
superuserCheckers []string
|
||||
|
||||
checkPrefix bool
|
||||
stripPrefix bool
|
||||
prefixes map[string]string
|
||||
|
||||
disableSuperuser bool
|
||||
|
@ -76,7 +77,6 @@ func Initialize(authOpts map[string]string, logLevel log.Level, version string)
|
|||
aclCheckers: make([]string, 0),
|
||||
userCheckers: make([]string, 0),
|
||||
superuserCheckers: make([]string, 0),
|
||||
checkPrefix: false,
|
||||
prefixes: make(map[string]string),
|
||||
}
|
||||
|
||||
|
@ -273,6 +273,7 @@ func (b *Backends) setPrefixes(authOpts map[string]string, backends []string) {
|
|||
|
||||
if !ok || strings.Replace(checkPrefix, " ", "", -1) != "true" {
|
||||
b.checkPrefix = false
|
||||
b.stripPrefix = false
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -282,6 +283,7 @@ func (b *Backends) setPrefixes(authOpts map[string]string, backends []string) {
|
|||
if !ok {
|
||||
log.Warn("Error: prefixes enabled but no options given, defaulting to prefixes disabled.")
|
||||
b.checkPrefix = false
|
||||
b.stripPrefix = false
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -291,10 +293,15 @@ func (b *Backends) setPrefixes(authOpts map[string]string, backends []string) {
|
|||
if len(prefixes) != len(backends) {
|
||||
log.Errorf("Error: got %d backends and %d prefixes, defaulting to prefixes disabled.", len(backends), len(prefixes))
|
||||
b.checkPrefix = false
|
||||
b.stripPrefix = false
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if authOpts["strip_prefix"] == "true" {
|
||||
b.stripPrefix = true
|
||||
}
|
||||
|
||||
for i, backend := range backends {
|
||||
b.prefixes[prefixes[i]] = backend
|
||||
}
|
||||
|
@ -355,8 +362,10 @@ func (b *Backends) AuthUnpwdCheck(username, password, clientid string) (bool, er
|
|||
return false, fmt.Errorf("backend %s not registered to check users", bename)
|
||||
}
|
||||
|
||||
// If the backend is JWT and the token was prefixed, then strip the token. If the token was passed without a prefix it will be handled in the common case.
|
||||
if bename == jwtBackend {
|
||||
// If the backend is JWT and the token was prefixed, then strip the token.
|
||||
// If the token was passed without a prefix it will be handled in the common case.
|
||||
// Also strip the prefix if the strip_prefix option was set.
|
||||
if bename == jwtBackend || b.stripPrefix {
|
||||
prefix := b.getPrefixForBackend(bename)
|
||||
username = strings.TrimPrefix(username, prefix+"_")
|
||||
}
|
||||
|
@ -414,8 +423,10 @@ func (b *Backends) AuthAclCheck(clientid, username, topic string, acc int) (bool
|
|||
return b.checkAcl(username, topic, clientid, acc)
|
||||
}
|
||||
|
||||
// If the backend is JWT and the token was prefixed, then strip the token. If the token was passed without a prefix then let it be handled in the common case.
|
||||
if bename == jwtBackend {
|
||||
// If the backend is JWT and the token was prefixed, then strip the token.
|
||||
// If the token was passed without a prefix then let it be handled in the common case.
|
||||
// Also strip the prefix if the strip_prefix option was set.
|
||||
if bename == jwtBackend || b.stripPrefix {
|
||||
prefix := b.getPrefixForBackend(bename)
|
||||
username = strings.TrimPrefix(username, prefix+"_")
|
||||
}
|
||||
|
|
|
@ -444,5 +444,53 @@ func TestBackends(t *testing.T) {
|
|||
|
||||
redis.Halt()
|
||||
})
|
||||
|
||||
Convey("When strip_prefix is true, the prefix will be stripped from the username prior to conducting checks", func() {
|
||||
authOpts["backends"] = "redis"
|
||||
authOpts["redis_register"] = "user, acl"
|
||||
authOpts["check_prefix"] = "true"
|
||||
authOpts["strip_prefix"] = "true"
|
||||
authOpts["prefixes"] = "redis"
|
||||
delete(authOpts, "disable_superuser")
|
||||
|
||||
username := "redis_test1"
|
||||
stripUsername := "test1"
|
||||
password := username
|
||||
passwordHash := "PBKDF2$sha512$100000$hgodnayqjfs0AOCxvsU+Zw==$dfc4LBGmZ/wB128NOD48qF5fCS+r/bsjU+oCXgT3UksAik73vIkXcPFydtbJKoIgnepNXP9t+zGIaR5wyRmXaA=="
|
||||
|
||||
redis, err := NewRedis(authOpts, log.DebugLevel, hashing.NewHasher(authOpts, "redis"))
|
||||
assert.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Insert a user to test auth.
|
||||
redis.conn.Set(ctx, stripUsername, passwordHash, 0)
|
||||
redis.conn.Set(ctx, fmt.Sprintf("%s:su", stripUsername), "true", 0)
|
||||
|
||||
b, err := Initialize(authOpts, log.DebugLevel, version)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
userCheck, err := b.AuthUnpwdCheck(username, password, clientid)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(userCheck, ShouldBeTrue)
|
||||
|
||||
redis.conn.SAdd(ctx, stripUsername+":racls", "test/redis")
|
||||
|
||||
aclCheck, err := b.AuthAclCheck(clientid, stripUsername, "test/redis", 1)
|
||||
So(err, ShouldBeNil)
|
||||
So(aclCheck, ShouldBeTrue)
|
||||
|
||||
userCheck, err = b.AuthUnpwdCheck(username, password, clientid)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(userCheck, ShouldBeTrue)
|
||||
|
||||
aclCheck, err = b.AuthAclCheck(clientid, stripUsername, "test/redis", 1)
|
||||
So(err, ShouldBeNil)
|
||||
So(aclCheck, ShouldBeTrue)
|
||||
|
||||
redis.Halt()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
2
go.sum
2
go.sum
|
@ -182,6 +182,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
|
@ -318,6 +319,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
Loading…
Reference in New Issue