Coder Social home page Coder Social logo

wiltonsr / ldapauth Goto Github PK

View Code? Open in Web Editor NEW
106.0 106.0 10.0 572 KB

An open source Traefik Middleware that enables authentication via LDAP in a similar way to Traefik Enterprise

Home Page: https://plugins.traefik.io/plugins/628c9eb7ffc0cd18356a979c/ldap-auth

License: Apache License 2.0

Makefile 1.09% Go 98.91%
authentication authentication-middleware gandalpher go go-ldap golang hacktoberfest ldap ldap-authentication plugin traefik-middleware traefik-plugin traefik-v2

ldapauth's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ldapauth's Issues

plugin seems to ignore spaces in `searchFilter`

tried this filter:
(&(memberOf=CN=Administratorzy domeny,CN=Users,DC=wupb,DC=lokalna)(objectClass=user)(sAMAccountName={{.Username}}))
it fails and i see this in the logs:

DEBUG: ldapAuth: 2022/12/01 12:15:30 restricted.go:51: Running in Search Mode
DEBUG: ldapAuth: 2022/12/01 12:15:30 restricted.go:51: Performing User BindDN Search
DEBUG: ldapAuth: 2022/12/01 12:15:30 restricted.go:51: Search Filter: '(&(memberOf=CN=Administratorzydomeny,CN=Users,DC=wupb,DC=lokalna)(sAMAccountName=myusername))'

using quotation marks around the group name doesn't seem to solve the problem, as far as i know spaces in group names are common in Active Directory

LDAP auth works, but creates a panic

The authentication with LDAP works, but it will create these panics as seen in first block. It is possible to use the app behind it, but after a while (i guess the session is dropped) it goes into more panics and it dies with "Internal Server Error" (500) as seen in the second block. After that I could only restart traefic to recover and the whole things starts over again.

traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Session details: &{ map[] 0xc002c84fc0 true {0xc0026aca00 {0xc002934e80 0xc002c8c388 406}} ldapAuth_session_token}
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:52: No session found! Trying to authenticate in LDAP
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Host: ldap.host.com
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Connect Address: ldap.host.com:636
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Running in Bind Mode
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Authenticating User: uid=user,ou=people,dc=host,dc=com
traefik  | INFO: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Authentication succeeded
traefik  | {"level":"error","module":"github.com/wiltonsr/ldapAuth","msg":"plugins-storage/sources/gop-3099684647/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/conn.go:264:2: panic","plugin":"plugin-ldapAuth","time":"2023-02-21T18:49:03Z"}
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Session details: &{ map[authenticated:true username:user] 0xc00077b1c0 false {0xc0026aca00 {0xc002934e80 0xc00198e800 406}} ldapAuth_session_token}
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:52: [no valid 'Authorization: Basic xxxx' header found in request]
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Session details: &{ map[authenticated:true username: user] 0xc001f10c40 false {0xc0026aca00 {0xc002934e80 0xc001950700 406}} ldapAuth_session_token}
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Session token Valid! Passing request...
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Session details: &{ map[authenticated:true username: user] 0xc002c85840 false {0xc0026aca00 {0xc002934e80 0xc002c8cbc0 406}} ldapAuth_session_token}
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Session token Valid! Passing request...
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:51: Session details: &{ map[authenticated:true username: user] 0xc000a96bc0 false {0xc0026aca00 {0xc002934e80 0xc002d18898 406}} ldapAuth_session_token}
traefik  | DEBUG: ldapAuth: 2023/02/21 18:49:03 restricted.go:52: [no valid 'Authorization: Basic xxxx' header found in request]

2nd block:

traefik  | DEBUG: ldapAuth: 2023/02/21 18:56:34 restricted.go:51: Session details: &{ map[] 0xc001f75100 true {0xc0026aca00 {0xc002934e80 0xc0019d2de0 406}} ldapAuth_session_token}
traefik  | DEBUG: ldapAuth: 2023/02/21 18:56:34 restricted.go:52: No session found! Trying to authenticate in LDAP
traefik  | DEBUG: ldapAuth: 2023/02/21 18:56:34 restricted.go:51: Host: ldap.host.com
traefik  | DEBUG: ldapAuth: 2023/02/21 18:56:34 restricted.go:51: Connect Address: ldap.host.com:636
traefik  | DEBUG: ldapAuth: 2023/02/21 18:56:34 restricted.go:51: Running in Bind Mode
traefik  | DEBUG: ldapAuth: 2023/02/21 18:56:34 restricted.go:51: Authenticating User: uid=user,ou=people,dc=host,dc=com
traefik  | {"level":"error","module":"github.com/wiltonsr/ldapAuth","msg":"plugins-storage/sources/gop-3099684647/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/request.go:50:2: panic","plugin":"plugin-ldapAuth","time":"2023-02-21T18:56:34Z"}
traefik  | {"level":"error","module":"github.com/wiltonsr/ldapAuth","msg":"plugins-storage/sources/gop-3099684647/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/bind.go:61:5: panic","plugin":"plugin-ldapAuth","time":"2023-02-21T18:56:34Z"}
traefik  | {"level":"error","module":"github.com/wiltonsr/ldapAuth","msg":"plugins-storage/sources/gop-3099684647/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/bind.go:100:3: panic","plugin":"plugin-ldapAuth","time":"2023-02-21T18:56:34Z"}
traefik  | {"level":"error","module":"github.com/wiltonsr/ldapAuth","msg":"plugins-storage/sources/gop-3099684647/src/github.com/wiltonsr/ldapAuth/ldapauth.go:232:5: panic","plugin":"plugin-ldapAuth","time":"2023-02-21T18:56:34Z"}
traefik  | {"level":"error","module":"github.com/wiltonsr/ldapAuth","msg":"plugins-storage/sources/gop-3099684647/src/github.com/wiltonsr/ldapAuth/ldapauth.go:125:6: panic","plugin":"plugin-ldapAuth","time":"2023-02-21T18:56:34Z"}

Panic for cache sessions while traefik starting

For version 0.0.19 I got a panic error
INFO: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: Starting ldap_auth@docker Middleware...
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: Enabled => 'true'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: LogLevel => 'DEBUG'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: URL => 'ldap://example.my.server'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: Port => '389'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: CacheTimeout => '300'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: CacheCookieName => 'ldapAuth_session_token'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: CacheKey => 'super-secret-key'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: UseTLS => 'true'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: StartTLS => 'true'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: CertificateAuthority => ''
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: InsecureSkipVerify => 'false'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: Attribute => 'uid'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: SearchFilter => ''
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: BaseDN => 'dc=example,dc=com'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: BindDN => 'cn=readonly,dc=example,dc=com'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: BindPassword => 'super_pass'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: ForwardUsername => 'true'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: ForwardUsernameHeader => 'Username'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: ForwardAuthorization => 'false'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: ForwardExtraLdapHeaders => 'false'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: WWWAuthenticateHeader => 'true'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: WWWAuthenticateHeaderRealm => ''
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: AllowedGroups => '[]'
DEBUG: ldapAuth: 2022/11/14 18:41:31 restricted.go:51: Username => ''
time="2022-11-14T18:41:31Z" level=error msg="plugins-storage/sources/gop-1256848229/src/github.com/wiltonsr/ldapAuth/vendor/github.com/gorilla/sessions/store.go:117:2: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2022-11-14T18:41:31Z" level=error msg="plugins-storage/sources/gop-1256848229/src/github.com/wiltonsr/ldapAuth/vendor/github.com/gorilla/sessions/store.go:52:11: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2022-11-14T18:41:31Z" level=error msg="plugins-storage/sources/gop-1256848229/src/github.com/wiltonsr/ldapAuth/ldapauth.go:105:12: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2022-11-14T18:41:31Z" level=error msg="Error in Go routine: plugins-storage/sources/gop-1256848229/src/github.com/wiltonsr/ldapAuth/vendor/github.com/gorilla/sessions/store.go:120:24: invalid type interface {}"
time="2022-11-14T18:41:31Z" level=error msg="Stack: goroutine 59 [running]:\nruntime/debug.Stack()\n\truntime/debug/stack.go:24 +0x65\ngithub.com/traefik/traefik/v2/pkg/safe.defaultRecoverGoroutine({0x3719e00, 0xc0034bdd58})\n\tgithub.com/traefik/traefik/v2/pkg/safe/routine.go:66 +0xa5\ngithub.com/traefik/traefik/v2/pkg/safe.GoWithRecover.func1.1()\n\tgithub.com/traefik/traefik/v2/pkg/safe/routine.go:56 +0x36\npanic({0x3719e00, 0xc0034bdd58})\n\truntime/panic.go:1038 +0x215\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:192 +0x145\npanic({0x3719e00, 0xc0034bdd58})\n\truntime/panic.go:1038 +0x215\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:192 +0x145\npanic({0x3719e00, 0xc0034bdd58})\n\truntime/panic.go:1038 +0x215\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:192 +0x145\npanic({0x3719e00, 0xc0034bdd58})\n\truntime/panic.go:1038 +0x215\ngithub.com/traefik/yaegi/interp.genValueRangeArray.func2(0x3447ca0)\n\tgithub.com/traefik/[email protected]/interp/value.go:272 +0x405\ngithub.com/traefik/yaegi/interp._range.func4(0xc002db3b80)\n\tgithub.com/traefik/[email protected]/interp/run.go:2803 +0x42\ngithub.com/traefik/yaegi/interp.runCfg(0xc001cc3d40, 0xc002db3b80, 0x0, 0x30332a0)\n\tgithub.com/traefik/[email protected]/interp/run.go:200 +0x2ac\ngithub.com/traefik/yaegi/interp.call.func9(0xc002db38c0)\n\tgithub.com/traefik/[email protected]/interp/run.go:1433 +0x94e\ngithub.com/traefik/yaegi/interp.runCfg(0xc001caf560, 0xc002db38c0, 0xc002c6a410, 0x2f95240)\n\tgithub.com/traefik/[email protected]/interp/run.go:200 +0x2ac\ngithub.com/traefik/yaegi/interp.call.func9(0xc002db36b0)\n\tgithub.com/traefik/[email protected]/interp/run.go:1433 +0x94e\ngithub.com/traefik/yaegi/interp.runCfg(0xc000e34a20, 0xc002db36b0, 0x39, 0x3037060)\n\tgithub.com/traefik/[email protected]/interp/run.go:200 +0x2ac\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func2.1({0xc0034b2120, 0x4, 0x8})\n\tgithub.com/traefik/[email protected]/interp/run.go:1022 +0x4a5\nreflect.Value.call({0xc0020c0a80, 0xc0020d7980, 0x7fd0e9badf18}, {0x3914939, 0x4}, {0xc002c6b418, 0x4, 0xc80038})\n\treflect/value.go:556 +0x845\nreflect.Value.Call({0xc0020c0a80, 0xc0020d7980, 0xc0034af8c0}, {0xc002c6b418, 0x4, 0x4})\n\treflect/value.go:339 +0xc5\ngithub.com/traefik/traefik/v2/pkg/plugins.middlewareBuilder.newHandler({{0xc0020c0a80, 0xc0020d7980, 0x13}, {0xc00209f920, 0xc0020d7c50, 0x13}}, {0x42e8f60, 0xc000c06f30}, {0x427e8a0, 0xc000c06f00}, ...)\n\tgithub.com/traefik/traefik/v2/pkg/plugins/middlewares.go:62 +0x336\ngithub.com/traefik/traefik/v2/pkg/plugins.(*Middleware).NewHandler(...)\n\tgithub.com/traefik/traefik/v2/pkg/plugins/middlewares.go:129\ngithub.com/traefik/traefik/v2/pkg/server/middleware.(*Builder).buildConstructor.func23({0x427e8a0, 0xc000c06f00})\n\tgithub.com/traefik/traefik/v2/pkg/server/middleware/middlewares.go:359 +0x3c\ngithub.com/traefik/traefik/v2/pkg/middlewares/tracing.Wrap.func1({0x427e8a0, 0xc000c06f00})\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/tracing/wrapper.go:24 +0x5a\ngithub.com/traefik/traefik/v2/pkg/server/middleware.(*Builder).BuildChain.func1({0x427e8a0, 0xc000c06f00})\n\tgithub.com/traefik/traefik/v2/pkg/server/middleware/middlewares.go:80 +0xf7\ngithub.com/containous/alice.Chain.Then({{0xc0034998f0, 0xc0034998f8, 0xc000c069c0}}, {0x427e5c0, 0xc0034998e0})\n\tgithub.com/containous/[email protected]/chain.go:51 +0x90\ngithub.com/traefik/traefik/v2/pkg/server/router.(*Manager).buildHTTPHandler(0xc002c6bd90, {0x42e8f60, 0xc000c069c0}, 0xc0033be460, {0xc002f93ae8, 0xc002c6b838})\n\tgithub.com/traefik/traefik/v2/pkg/server/router/router.go:190 +0x5a5\ngithub.com/traefik/traefik/v2/pkg/server/router.(*Manager).buildRouterHandler(0xc002c6bd90, {0x42e8f60, 0xc000c069c0}, {0xc002f93ae8, 0x13}, 0xc00349e5c0)\n\tgithub.com/traefik/traefik/v2/pkg/server/router/router.go:144 +0xac\ngithub.com/traefik/traefik/v2/pkg/server/router.(*Manager).buildEntryPointHandler(0x42e8ef0, {0x42e8f60, 0xc000b77a70}, 0x1)\n\tgithub.com/traefik/traefik/v2/pkg/server/router/router.go:114 +0x1ea\ngithub.com/traefik/traefik/v2/pkg/server/router.(*Manager).BuildHandlers(0xc002c6bd90, {0x42e8ef0, 0xc00013e020}, {0xc0020d4e80, 0x0, 0x4}, 0x0)\n\tgithub.com/traefik/traefik/v2/pkg/server/router/router.go:68 +0x27b\ngithub.com/traefik/traefik/v2/pkg/server.(*RouterFactory).CreateRouters(0xc0020e4460, 0xc003329380)\n\tgithub.com/traefik/traefik/v2/pkg/server/routerfactory.go:78 +0x26a\nmain.switchRouter.func1({0xc000b8ebd0, 0xc002ffb800, 0xc0033154c0, 0xc000b8ec00})\n\tgithub.com/traefik/traefik/v2/cmd/traefik/traefik.go:388 +0x92\ngithub.com/traefik/traefik/v2/pkg/server.(*ConfigurationWatcher).applyConfigurations(0xc0020e44d0, {0x42e8eb8, 0xc00009d240})\n\tgithub.com/traefik/traefik/v2/pkg/server/configurationwatcher.go:172 +0x225\ngithub.com/traefik/traefik/v2/pkg/safe.(*Pool).GoCtx.func1()\n\tgithub.com/traefik/traefik/v2/pkg/safe/routine.go:36 +0x66\ngithub.com/traefik/traefik/v2/pkg/safe.GoWithRecover.func1()\n\tgithub.com/traefik/traefik/v2/pkg/safe/routine.go:59 +0x5b\ncreated by github.com/traefik/traefik/v2/pkg/safe.GoWithRecover\n\tgithub.com/traefik/traefik/v2/pkg/safe/routine.go:53 +0x77\n"

Intermittent authentication failures

First of all, thanks a lot for all the work!

Now without further ado: Occasionally - circa once in 6 attempts, the login fails with valid credentials and the user is asked for credential again. The response time is immediate (no timeout).

Middleware configuration:

  ---
  apiVersion: traefik.containo.us/v1alpha1
  kind: Middleware
  metadata:
    annotations:
    name: example-ldap-auth
    namespace: traefik
  spec:
    plugin:
      ldapAuth:
        Attribute: cn
        BaseDn: ou=users,ou=nethz,ou=id,ou=auth,o=example,c=ch
        BindDn: cn=proxy_user,ou=admins,ou=bar,ou=auth,o=example,c=ch
        BindPassword: "..."
        Enabled: "true"
        LogLevel: INFO
        Port: 636
        SearchFilter: ({{.Attribute}}={{.Username}})
        URL: ldaps://ldaps.example.com

Errors visible in the log:

ERROR: ldapAuth: 2022/10/06 07:06:53 restricted.go:51: LDAP Result Code 200 "Network Error": ldap: response channel closed
ERROR: ldapAuth: 2022/10/06 07:06:53 restricted.go:51: Authentication failed

time="2022-10-06T07:22:58Z" level=error msg="2022/10/06 07:22:58 Received unexpected message 1, false" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
ERROR: ldapAuth: 2022/10/06 07:22:58 restricted.go:51: BindDN Error: LDAP Result Code 200 "Network Error": ldap: response channel closed
ERROR: ldapAuth: 2022/10/06 07:22:58 restricted.go:51: Authentication failed

ERROR: ldapAuth: 2022/10/06 07:38:21 restricted.go:51: BindDN Error: LDAP Result Code 200 "Network Error": ldap: response channel closed
ERROR: ldapAuth: 2022/10/06 07:38:21 restricted.go:51: Authentication failed

ERROR: ldapAuth: 2022/10/06 07:49:49 restricted.go:51: BindDN Error: unable to read LDAP response packet: unexpected EOF
ERROR: ldapAuth: 2022/10/06 07:49:49 restricted.go:51: Authentication failed
ERROR: ldapAuth: 2022/10/06 07:49:49 restricted.go:51: BindDN Error: unable to read LDAP response packet: unexpected EOF
ERROR: ldapAuth: 2022/10/06 07:49:49 restricted.go:51: Authentication failed

INFO: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: Authenticating User: cn=mminar,ou=users,ou=nethz,ou=id,ou=auth,o=example,c=ch
INFO: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: Authentication succeeded
10.253.58.254 - mminar [07/Oct/2022:14:20:12 +0000] "GET /script.js HTTP/2.0" 200 108434 "-" "-" 27378 "monitoring-alertmanager-alertmanager-foo-bar-example-ch@kubernetes" "http://10.205.243.230:9093" 64ms
INFO: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: Authenticating User: cn=mminar,ou=users,ou=nethz,ou=id,ou=auth,o=example,c=ch
INFO: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: Authenticating User: cn=mminar,ou=users,ou=nethz,ou=id,ou=auth,o=example,c=ch
INFO: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: Authenticating User: cn=mminar,ou=users,ou=nethz,ou=id,ou=auth,o=example,c=ch
ERROR: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: search filter return multiple entries (2)
ERROR: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: Authentication failed
INFO: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: Authentication succeeded
10.253.58.254 - - [07/Oct/2022:14:20:12 +0000] "GET /api/v2/receivers HTTP/2.0" 401 68 "-" "-" 27382 "monitoring-alertmanager-alertmanager-foo-bar-example-ch@kubernetes" "-" 30ms
ERROR: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: search silter return empty result
ERROR: ldapAuth: 2022/10/07 14:20:12 restricted.go:51: Authentication failed
10.253.58.254 - - [07/Oct/2022:14:20:12 +0000] "GET /api/v2/alerts/groups?silenced=false&inhibited=false&active=true HTTP/2.0" 401 60 "-" "-" 27383 "monitoring-alertmanager-alertmanager-foo-bar-example-ch@kubernetes" "-" 31ms

These are our helm values (with some obfuscation applied):

---
metrics:
  prometheus:
    addRoutersLabels: true
service:
  spec:
    loadBalancerIP: 123.123.123.123
    externalTrafficPolicy: Local
env:
  - name: http_proxy
    value: http://proxy.example.com:3128
  - name: https_proxy
    value: http://proxy.example.com:3128
  - name: no_proxy
    value: localhost,127.0.0.1,10.206.0.0/16,10.205.0.0/16,.svc,.cluster.local,.local,.cilium,123.123.123.123,123.123.123.0/27,.foo.bar.example.com,ldaps*.example.com
hostNetwork: false
deployment:
  replicas: 2
autoscaling:
  enabled: true
  maxReplicas: 5
ingressClass:
  enabled: true
  isDefaultClass: true
ingressRoute:
  dashboard:
    enabled: false
logs:
  access:
    enabled: true
  general:
    level: INFO
experimental:
  plugins:
    enabled: true
globalArguments:
  - --global.checknewversion
  - --experimental.plugins.ldapAuth.modulename=github.com/wiltonsr/ldapAuth
  - --experimental.plugins.ldapAuth.version=v0.0.14
  - --providers.kubernetescrd.allowCrossNamespace=true

We don't see the same problem with grafana which has its own built-in LDAP authentication mechanism, which is configured more or less the same as this plugin.

Any hint/advice would be appreciated.

allowedGroups sintax

Hello, i have a problem with allowedGroups module in plugin.
Have config:

http:
  middlewares:
    ldap-auth:
      plugin:
        ldapAuth:
          Attribute: "uid"
          BaseDn: "cn=users,cn=accounts,dc=org,dc=local"
          Enabled: true
          Url: "ldap://freeipa.org.local"
          LogLevel: "DEBUG"
          allowedGroups:
            - cn=test-group,cn=groups,cn=accounts,dc=org,dc=local

I have testuser in test-group. But traefik cant authenticate testuser:

Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:52: No session found! Trying to authenticate in LDAP
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Host: freeipa.org.local
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Connect Address: freeipa.org.local:389
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Running in Bind Mode
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Authenticating User: uid=testuser,cn=users,cn=accounts,dc=org,dc=local
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Searching Group: 'cn=test-group,cn=groups,cn=accounts,dc=org,dc=local' with User: 'uid=testuser,cn=users,cn=accounts,dc=org,dc=local'
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: INFO: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: LDAP Result Code 12 "Unavailable Critical Extension": Bad search filter
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: User: 'testuser' not found in Group: 'cn=test-group,cn=groups,cn=accounts,dc=org,dc=local'
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: ERROR: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: LDAP Result Code 12 "Unavailable Critical Extension": Bad search filter
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: User 'testuser' does not match any allowed users nor allowed groups.
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:52: [LDAP Result Code 12 "Unavailable Critical Extension": Bad search filter
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: User 'testuser' does not match any allowed users nor allowed groups.]

i made a workaround using searchmode with
searchFilter: (&(memberOf=cn=test-group,cn=groups,cn=accounts,dc=org,dc=local)({{.Attribute}}={{.Username}}))
and it works, but would be great to understand why normal way doesn't work.
Maybe it's because of "memberOf" field? Didnt see this in sources.

LDAP Bind needed to complete the connection

Hello,

Thanks for your great plugin!
Unfortunately, I can't use it because my AD doesn't support anonymous connection.

As you can see in the log, authentication failed because no bind was performed (LdapErr: DSID-0C090A71).

time="2022-01-06T13:02:04+01:00" level=error msg="2022/01/06 13:02:04 Filter => (sAMAccountname=kichetof)" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2022-01-06T13:02:04+01:00" level=error msg="2022/01/06 13:02:04 Attributes => [sAMAccountname]" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
time="2022-01-06T13:02:04+01:00" level=error msg="2022/01/06 13:02:04 &{[] [] []}" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
time="2022-01-06T13:02:04+01:00" level=error msg="2022/01/06 13:02:04 LDAP Result Code 1 \"Operations Error\": 000004DC: LdapErr: DSID-0C090A71, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v3839\x00" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2022-01-06T13:02:04+01:00" level=error msg="2022/01/06 13:02:04 Search failed" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2022-01-06T13:02:04+01:00" level=error msg="2022/01/06 13:02:04 Authentication failed" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth

My middleware configuration:

[http.middlewares]
  [http.middlewares.admin-auth.plugin.ldapAuth]
    enabled = "true"
    host = "ldap://x.x.x.x"
    debug = "true"
    port = "389"
    baseDn = "OU=Admin,DC=foo,DC=bar,DC=co"
    userUniqueId = "sAMAccountname"

In the go-ldap library, they're the possibility to perform a bind to the server.

What do you think about added it to the plugin? (I've no knowledge in Go to create a PR ๐Ÿ˜…)

Many thanks for your help!
Tof

Issue with using encrypted connections

Regular unencrypted connections work. However, both using SSL and StartTLS fails.
This is the error that is shown in the log:
DEBUG: ldapAuth: 2024/03/14 10:53:07 restricted.go:52: [LDAP Result Code 200 "Network Error": TLS handshake failed (remote error: tls: handshake failure)]

For SSL I used ldaps:// instead of ldap and port 636

I am running traefik with the official docker image: traefik:v2.11.0

I was able to install ldapsearch and succesfully connect using SSL and StartTLS in the docker image.

This is the current configuration I'm trying to use with the yml dynamic file provider:

http:
  middlewares:
    ldap_auth:
      plugin:
        ldapAuth:
          Enabled: true
          LogLevel: "DEBUG"
          Url: "ldap://mydomain.example"
          Port: 389
          StartTLS: true
          insecureSkipVerify: true
          BaseDN: "dc=company,dc=local"
          Attribute: "uid"
          BindDN: "cn=read,dc=company,dc=local"
          BindPassword: "<password>"
          SearchFilter: (\{\{.Attribute\}\}=\{\{.Username\}\})

Feel free to ask for more debugging information.

Customize settings per container

Apologies if I am missing something in documentation or examples, but is there a straight forward way to have per container settings (for example, a different set of Allowed Groups) without duplicating common settings such as LDAP URL?

Support TLS LDAP Server

Create a startTLSoption.

Optional, Default=false

It will instructs ldapAuth to issue a StartTLS request when initializing the connection with the LDAP server.

I can't define 'searchFilter' using the File provider

I can't define searchFilter in dynamic configuration when using the File provider.
When I set the config like:

http:
  routers:   ...
  services:  ...

  middlewares:
    my-ldapAuth:
      plugin:
        ldapAuthPlugin:
          Enabled: true
          LogLevel: DEBUG
          Url: ldap://someserver
          Port: 389
          BaseDN: DC=com
          BindDN: CN=ldapuser,OU=HUB,DC=com
          BindPassword: Pa$$w0rd
          Attribute: sAMAccountName
          SearchFilter: (&(objectClass=user)(!(objectClass=computer))({{.Attribute}}={{.Username}}))         

Then when I run Traefik I get the error:

traefik    | time="2022-01-20T10:04:58Z" level=info msg="Starting provider *file.Provider {\"watch\":true,\"filename\":\"/configurations/dynamic.yml\"}"
traefik    | time="2022-01-20T10:04:58Z" level=error msg="Cannot start the provider *file.Provider: template: /configurations/dynamic.yml:45:72: executing \"/configurations/dynamic.yml\" at <.Attribute>: can't evaluate field Attribute in type bool"

As a workaround, I specified my filter as the default value of an option SearchFilter in the file ldapauth.go:

  ...
// CreateConfig creates the default plugin configuration.
func CreateConfig() *Config {
        return &Config{
                Enabled:        true,
                       ...
                SearchFilter:   "(&(objectClass=user)(!(objectClass=computer))({{.Attribute}}={{.Username}}))",
                       ...
                Username:     "",
        }
}

[Traefik Plugin Catalog] Plugin Analyzer has detected a problem.

The plugin was not imported into Traefik Plugin Catalog.

Cause:

failed to run the plugin with Yaegi: the load of the plugin takes too much time(10s), or an error, inside the plugin, occurs during the load: reflect: Call using *interp.node as type func() hash.Hash

Traefik Plugin Analyzer will restart when you will close this issue.

If you believe there is a problem with the Analyzer or this issue is the result of a false positive, please contact us.

Add support for Active Directory nested groups

Hi,

I have been using this plugin for a little bit now. One thing I noticed is that the group filter only applies for direct members and does not take into account users in nested groups.

I have submitted a pull request adding a criterion to the group filter OR clause that would include nested Active Directory groups.

PR here

Support AllowedGroups

Create a allowedGroups option.

Optional, Default=""

It will be a list of LDAP group DNs that users could be members of to be granted access. If a user is in any one of the listed groups, then that user is granted access.

If setted to an empty list or nil will allow all users that have an LDAP account to log in, without performing any group membership checks.

Unfortunately, traefik's option parser does not work with elements containing commas, which is the case with LDAP groups. So this issue will be suspended until we have a definition of the issue.

Username header does not get set on subsequent requests

Thanks a lot for this super-useful plugin!

The ForwardUsername setting works fine for the first request passed through the ldapAuth middleware, but will not get forwarded for subsequent requests.

Steps to reproduce:

  1. Enable ForwardUsername in the middleware config
  2. Authenticate with a request that is behind the ldapAuth middleware. Using traefik/whoami as the secured service works great for troubleshooting
  3. Observe that the username header is set as expected.
  4. Refresh the page to re-send the request
  5. The username header is not set anymore.

I will contribute a PR fixing this issue in a moment.

allowedGroups query

Hi,

I have a question regarding the User matching in given DN's of allowed Groups.

I have openLDAP roles, they look like this:

dn: uid=1234,ou=roles,ou=test,ou=test_service,o=some_org,c=some_country
description: some description
o: my_test
displayName: test_role
uid: 1234
cn: test_role
ou: test_role
objectClass: organizationalUnit
objectClass: OpenLDAPou
objectClass: uidObject
objectClass: spCategory
mail: some_mail@address
member: uid=member1,ou=users,ou=test,ou=test_service,o=some_org,c=some_country
member: uid=member2,ou=users,ou=test,ou=test_service,o=some_org,c=some_country

users look like this:

dn: uid=member1,ou=users,ou=test,ou=test_service,o=some_org,c=some_country
displayName::1274z90==
cn:: 12oi8u51395i==
objectClass: person
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: spPerson
sn: Name
employeeNumber: 1852375
givenName:: 1274z90==
ou: abbreviation
mail: [email protected]
uid: member1

relevant plugin yaml config is like:

attribute: uid
baseDn: ou=users,ou=test,ou=test_service,o=some_org,c=some_country
allowedGroups:
  - "uid=1234,ou=roles,ou=test,ou=test_service,o=some_org,c=some_country"

The user authentication works fine, but it doesn't seem to find the user as members:

DEBUG: ldapAuth: 2023/02/14 09:14:44 restricted.go:52: No session found! Trying to authenticate in LDAP
DEBUG: ldapAuth: 2023/02/14 09:14:44 restricted.go:51: Host: *****
DEBUG: ldapAuth: 2023/02/14 09:14:44 restricted.go:51: Connect Address: **** 
DEBUG: ldapAuth: 2023/02/14 09:14:49 restricted.go:51: Running in Bind Mode
DEBUG: ldapAuth: 2023/02/14 09:14:49 restricted.go:51: Authenticating User: uid=member1,ou=users,ou=test,ou=test_service,o=some_org,c=some_country
DEBUG: ldapAuth: 2023/02/14 09:14:49 restricted.go:51: Searching Group: 'uid=1234,ou=roles,ou=test,ou=test_service,o=some_org,c=some_country' with User: 'uid=member1,ou=users,ou=test,ou=test_service,o=some_org,c=some_country'
ERROR: ldapAuth: 2023/02/14 09:14:49 restricted.go:51: %!s(<nil>)
DEBUG: ldapAuth: 2023/02/14 09:14:49 restricted.go:52: [<nil>]

A ldap search filter like "(member=uid=member1,ou=users,ou=test,ou=test_service,o=some_org,c=some_country)" with baseDN "uid=1234,ou=roles,ou=test,ou=test_service,o=some_org,c=some_country" should work.

Why it doesn't match? Does it query for another attribute than member maybe? Could I work around somehow with a searchfilter?

Cheers!
And thanks a lot for sharing this plugin!

ldapurl must include port

This works:

        - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.url=ldap://myldapurl:13374242
        - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.port=389

This does not:


        - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.url=ldap://myldapurl
        - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.port=389

It seems like the changes you made recently to https://github.com/wiltonsr/ldapAuth/blob/master/ldapauth.go will take the port number you specify in. url, discard it, and use the port you specify in .port

However, if you dont specify a port in the url, it retuns a blank host when trying to connect, and fails.

[FEATURE] Multiple Simultaneous LDAP Authentication Requests with 2FA

We are using your middleware between the browser and restricted HTML content. Suppose the authentication cookie expires while the browser has old HTML content from before the expiration. In that case, the browser may initiate a cascade of layered authentication requests to the same protected endpoint for various assets (fresh HTML + updated versions of cached files + images). When this happens, the LDAP authentication is triggered for each asset simultaneously.

This is not an urgent problem for basic LDAP deployments, but more advanced setups with two-factor authentication (e.g., Duo) can subsequently trigger several simultaneous alerts and their required 2FA notifications.

Is there a way to sequence multiple requests to the same LDAP resource before successful or failed authentication, where any pending requests for the same client or requesting IP inherit the decision of whichever LDAP response is received first? The issue we are experiencing is a single browser refresh will trigger a dozen LDAP requests and, therefore, a dozen layered 2FA notifications in less than a second.

Integrity check failed

Hi,

I wanted to try this plugin, but I get this error:
traefik error: failed to check archive integrity of the plugin github.com/wiltonsr/ldapAuth: plugin integrity check failed

My config looks like this:

pilot:
        token: "<my_token>"
experimental:
        plugins:
                ldapAuth:
                        moduleName: "github.com/wiltonsr/ldapAuth"
                        version: "v0.0.9"

What am I doing wrong?

Regards,
Dorian

ldapAuth should have some level of caching

I have a Kibana server behind Traefik (v2.9.1) with the ldapAuth plugin (v0.0.17) and I can see 14 authentication requests via the ldapAuth logs just by accessing / on the server. The browser seems to cache the credentials, or perhaps that is happening in ldapAuth but it does show 14 requests being sent to my LDAP server and all of them are authenticated successfully. This isn't a fail-and-retry scenario. I was able to replicate this with a simpler web service just by refreshing the page it authenticates against LDAP in the log even though I don't get a credential prompt in the browser. Is there some way to cache an authentication for an hour or any other configurable amount of time?

Parsing errors with certain CN formats

Have been getting plugin crashes when attempting to authenticate certain users against groups. I suspect this is caused by the format of the user's CN string. Some users in our LDAP look like this and work normally:
CN=Firstname Lastname

Others look like this and crash the plugin:
CN=Firstname Lastname (f.lastname)

Full logs:

DEBUG: ldapAuth: 2022/11/03 11:24:06 restricted.go:51: Search Filter: '(sAMAccountname=f.lastname)'
INFO: ldapAuth: 2022/11/03 11:24:06 restricted.go:51: Authenticating User: CN=Firstname Lastname,OU=USA,OU=Users,DC=orgname,DC=sys
DEBUG: ldapAuth: 2022/11/03 11:24:07 restricted.go:51: Searching Group: 'CN=User Group,OU=DistributionLists,DC=orgname,DC=sys' with User: 'CN=Firstname Lastname,OU=USA,OU=Users,DC=orgname,DC=sys'
DEBUG: ldapAuth: 2022/11/03 11:24:07 restricted.go:51: User: 'CN=Firstname Lastname,OU=USA,OU=Users,DC=orgname,DC=sys' found in Group: 'CN=User Group,OU=DistributionLists,DC=orgname,DC=sys'
INFO: ldapAuth: 2022/11/03 11:24:07 restricted.go:51: Authentication succeeded

DEBUG: ldapAuth: 2022/11/03 11:19:55 restricted.go:51: Search Filter: '(sAMAccountname=f.lastname)'
INFO: ldapAuth: 2022/11/03 11:19:55 restricted.go:51: Authenticating User: CN=Firstname Lastname (f.lastname),OU=ISR,OU=Users,DC=orgname,DC=sys
DEBUG: ldapAuth: 2022/11/03 11:19:55 restricted.go:51: Searching Group: 'CN=User Group,OU=DistributionLists,DC=orgname,DC=sys' with User: 'CN=Firstname Lastname (f.lastname),OU=ISR,OU=Users,DC=orgname,DC=sys'
time="2022-11-03T11:19:55Z" level=error msg="plugins-storage/sources/gop-2386433808/src/github.com/wiltonsr/ldapAuth/ldapauth.go:258:9: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2022-11-03T11:19:55Z" level=error msg="plugins-storage/sources/gop-2386433808/src/github.com/wiltonsr/ldapAuth/ldapauth.go:125:6: panic" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
time="2022-11-03T11:19:55Z" level=error msg="Recovered from panic in HTTP handler [192.168.5.26:50528 - /favicon.ico]: reflect: call of reflect.Value.Field on zero Value" middlewareName=traefik-internal-recovery middlewareType=Recovery
time="2022-11-03T11:19:55Z" level=error msg="Stack: goroutine 6633 [running]:\ngithub.com/traefik/traefik/v2/pkg/middlewares/recovery.recoverFunc({0x44b2cc0, 0xc002086690}, 0xc0005eab00)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/recovery/recovery.go:46 +0x225\npanic({0x323fc20, 0xc001b3e120})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:192 +0x148\npanic({0x323fc20, 0xc001b3e120})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:192 +0x148\npanic({0x323fc20, 0xc001b3e120})\n\truntime/panic.go:884 +0x212\nreflect.Value.Field({0x0?, 0x0?, 0x3337680?}, 0xc001fa28a0?)\n\treflect/value.go:1266 +0xe5\nreflect.Value.FieldByIndex({0x0?, 0x0?, 0x8cdf1a?}, {0xc0011a1c40?, 0xc001bc38e8?, 0x2?})\n\treflect/value.go:1299 +0x66\ngithub.com/traefik/yaegi/interp.getPtrIndexSeq.func2(0xc001a40a50?)\n\tgithub.com/traefik/[email protected]/interp/run.go:2062 +0xcb\ngithub.com/traefik/yaegi/interp.runCfg(0xc000d9b8c0, 0xc001a40a50, 0xc0010fab28?, 0x30bcb40?)\n\tgithub.com/traefik/[email protected]/interp/run.go:200 +0x29d\ngithub.com/traefik/yaegi/interp.call.func9(0xc00153d600)\n\tgithub.com/traefik/[email protected]/interp/run.go:1438 +0x965\ngithub.com/traefik/yaegi/interp.runCfg(0xc000d658c0, 0xc00153d600, 0x39?, 0x38ba800?)\n\tgithub.com/traefik/[email protected]/interp/run.go:200 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func2.1({0xc0021d1cb0, 0x2, 0x4?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1022 +0x487\ngithub.com/traefik/yaegi/stdlib._net_http_Handler.ServeHTTP(...)\n\tgithub.com/traefik/[email protected]/stdlib/go1_19_net_http.go:290\ngithub.com/traefik/traefik/v2/pkg/middlewares/accesslog.(*FieldHandler).ServeHTTP(0xc001f425c0, {0x44b2cc0, 0xc002086690}, 0x32832e0?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/accesslog/field_middleware.go:31 +0x122\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc002b35c20, {0x44b2cc0, 0xc002086690}, 0xc0005eab00)\n\tgithub.com/gorilla/[email protected]/mux.go:141 +0x24c\ngithub.com/traefik/traefik/v2/pkg/middlewares/recovery.(*recovery).ServeHTTP(0xc0013bd300?, {0x44b2cc0?, 0xc002086690?}, 0x30b68c0?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/recovery/recovery.go:32 +0x82\ngithub.com/traefik/traefik/v2/pkg/middlewares/accesslog.(*FieldHandler).ServeHTTP(0xc001f43e40, {0x44b2cc0, 0xc002086690}, 0x203000?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/accesslog/field_middleware.go:31 +0x122\ngithub.com/traefik/traefik/v2/pkg/middlewares/snicheck.SNICheck.ServeHTTP({{0x4494fc0?, 0xc001f43e40?}, 0xc002048b40?}, {0x44b2cc0, 0xc002086690}, 0xc0005eab00)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/snicheck/snicheck.go:49 +0x189\ngithub.com/traefik/traefik/v2/pkg/middlewares.(*HTTPHandlerSwitcher).ServeHTTP(0x4108c7?, {0x44b2cc0, 0xc002086690}, 0x448c301?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/handler_switcher.go:23 +0x62\ngithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator.(*RequestDecorator).ServeHTTP(0xc00011cea8, {0x44b2cc0, 0xc002086690}, 0xc0005eaa00, 0xc002286b80)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator/request_decorator.go:47 +0x30e\ngithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator.WrapHandler.func1.1({0x44b2cc0?, 0xc002086690?}, 0xc0021d1b60?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator/request_decorator.go:89 +0x68\nnet/http.HandlerFunc.ServeHTTP(0xc000130e60?, {0x44b2cc0?, 0xc002086690?}, 0x9?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders.(*XForwarded).ServeHTTP(0xc000130e60, {0x44b2cc0, 0xc002086690}, 0xc0005eaa00)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders/forwarded_header.go:192 +0xca\nnet/http.AllowQuerySemicolons.func1({0x44b2cc0, 0xc002086690}, 0xc0005eaa00)\n\tnet/http/server.go:2974 +0x223\nnet/http.HandlerFunc.ServeHTTP(0x0?, {0x44b2cc0?, 0xc002086690?}, 0xc002916000?)\n\tnet/http/server.go:2109 +0x2f\nnet/http.serverHandler.ServeHTTP({0x120?}, {0x44b2cc0, 0xc002086690}, 0xc0005eaa00)\n\tnet/http/server.go:2947 +0x30c\nnet/http.initALPNRequest.ServeHTTP({{0x44bf310?, 0xc000a98120?}, 0xc0010ea700?, {0xc00025c4b0?}}, {0x44b2cc0, 0xc002086690}, 0xc0005eaa00)\n\tnet/http/server.go:3556 +0x245\ngolang.org/x/net/http2.(*serverConn).runHandler(0x44acfa0?, 0x63654c0?, 0x0?, 0x0?)\n\tgolang.org/x/[email protected]/http2/server.go:2248 +0x83\ncreated by golang.org/x/net/http2.(*serverConn).processHeaders\n\tgolang.org/x/[email protected]/http2/server.go:1958 +0x5b9\n" middlewareName=traefik-internal-recovery middlewareType=Recovery

Multiple auth requests

Hello, we have a unsecured web-server with swagger and static pages.
When i use ldapuath plugin to acces static page it shows me basic auth request and after entering credentials page opens.
If i reload page, auth is required again, but i cant authenticate. After entering creds auth request opens again and again.
Thats what i see in logs:

Aug 31 11:43:31 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:31 restricted.go:51: User: 'uid=plakun,cn=users,cn=accounts,dc=domain1,dc=domain2' found in Group: 'cn=test,cn=groups,cn=accounts,dc=domain1,dc=domain2'
Aug 31 11:43:31 infra-internal-lb-01 traefik[3818996]: INFO: ldapAuth: 2023/08/31 11:43:31 restricted.go:51: Authentication succeeded
Aug 31 11:43:34 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:34 restricted.go:51: Session details: &{ map[authenticated:true username:plakun] 0xc000a5bc40 false {0xc0027e6140 {0xc00163ef00 0xc000013080 406}} ldapAuth_session_token}
Aug 31 11:43:34 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:34 restricted.go:51: Session token Valid! Passing request...
Aug 31 11:43:39 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:39 restricted.go:51: Session details: &{ map[authenticated:true username:plakun] 0xc0013dfd80 false {0xc0027e6140 {0xc00163ef00 0xc00188d570 406}} ldapAuth_session_token}
Aug 31 11:43:39 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:39 restricted.go:51: Session token Valid! Passing request...
Aug 31 11:43:39 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:39 restricted.go:51: Session details: &{ map[authenticated:true username:plakun] 0xc002085780 false {0xc0027e6140 {0xc00163ef00 0xc00090c8d8 406}} ldapAuth_session_token}
Aug 31 11:43:39 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:39 restricted.go:51: Session token Valid! Passing request...
Aug 31 11:43:41 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:41 restricted.go:51: Session details: &{ map[authenticated:true username:plakun] 0xc002879400 false {0xc0027e6140 {0xc00163ef00 0xc00090d758 406}} ldapAuth_session_token}
Aug 31 11:43:41 infra-internal-lb-01 traefik[3818996]: DEBUG: ldapAuth: 2023/08/31 11:43:41 restricted.go:51: Session token Valid! Passing request...

Same behavior is when i open swagger-ui page.

My config:

http:
  middlewares:
    ldap-auth:
      plugin:
        ldapAuth:
          Attribute: "uid"
          BaseDn: "cn=users,cn=accounts,dc=domain1,dc=domain2"
          Enabled: true
          Url: "ldap://freeipa.local"
          LogLevel: "DEBUG"
          wwwAuthenticateHeader: true
          cacheTimeout: 300
          allowedGroups:
            - cn=test,cn=groups,cn=accounts,dc=domain1,dc=domain2

Try to test in Postman.
First GET request to swagger-ui with basic auth headers gets 200\OK. Another request with same cookie that i'v got at first try gives me:
{"timestamp":"2023-08-31T08:49:36.511+00:00","status":401,"error":"Unauthorized","path":"/swagger-ui/index.html"}

Pb with lib go-ldap v3: Call using int64 as type string

I try to install middleware ldapAuth v0.0.21 whith traefik 2.9.8n but I get this error just after connecting to the ldap

time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/request.go:50:2: panic" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth

func (l *Conn) readPacket(msgCtx *messageContext) (*ber.Packet, error) {
	l.Debug.Printf("**%d**: waiting for response", msgCtx.id)`

msgCtx.id is a string, but waited en integer


time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/bind.go:61:5: panic" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth

time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/bind.go:100:3: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth

time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/ldapauth.go:232:5: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth

time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/ldapauth.go:125:6: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth

time="2023-03-17T12:44:34Z" level=error msg="Recovered from panic in HTTP handler [192.168.32.1:59358 - /]: reflect: **Call using int64 as type string**" middlewareName=traefik-internal-recovery middlewareType=Recovery


time="2023-03-17T12:44:34Z" level=error msg="Stack: goroutine 138 [running]:\ngithub.com/traefik/traefik/v2/pkg/middlewares/recovery.recoverFunc({0x52e0cb0, 0xc000efd410}, 0xc001b27e00)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/recovery/recovery.go:46 +0x225\npanic({0x3a3ed60, 0xc001f71690})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc001f71690})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc001f71690})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc001f71690})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc001f71690})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc001f71690})\n\truntime/panic.go:884 +0x212\nreflect.Value.call({0x3b06380?, 0xc001a17890?, 0xc0016ae7e0?}, {0x472a1fe, 0x4}, {0xc001a178c0, 0x2, 0xc0012c9988?})\n\treflect/value.go:440 +0x1abf\nreflect.Value.Call({0x3b06380?, 0xc001a17890?, 0xc001efd900?}, {0xc001a178c0?, 0xc0012c9988?, 0x196?})\n\treflect/value.go:368 +0xbc\ngithub.com/traefik/yaegi/interp.call.func9.2({0xc001a178c0?, 0xc001a17890?, 0xc001533c00?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1301 +0x3c\ngithub.com/traefik/yaegi/interp.call.func9(0xc0026aafd0)\n\tgithub.com/traefik/[email protected]/interp/run.go:1326 +0x1265\ngithub.com/traefik/yaegi/interp.runCfg(0xc001efa280, 0xc0026aafd0, 0x2?, 0xc001b95b80?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc0026952c0, 0x1, 0x1?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1015 +0x4a5\nreflect.Value.call({0xc001df3740?, 0xc001a150b0?, 0x41057f?}, {0x472a1fe, 0x4}, {0xc0026952a8, 0x1, 0xc00229aa90?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0xc001df3740?, 0xc001a150b0?, 0x455292?}, {0xc0026952a8?, 0x46c6b00?, 0x1?})\n\treflect/value.go:368 +0xbc\ngithub.com/traefik/yaegi/interp.call.func9.2({0xc0026952a8?, 0xc001a150b0?, 0xc0016ac100?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1301 +0x3c\ngithub.com/traefik/yaegi/interp.call.func9(0xc0025c58c0)\n\tgithub.com/traefik/[email protected]/interp/run.go:1326 +0x1265\ngithub.com/traefik/yaegi/interp.runCfg(0xc00129de00, 0xc0025c58c0, 0x2?, 0xc001c04040?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc002595098, 0x1, 0x1?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1015 +0x4a5\nreflect.Value.call({0xc001df3aa0?, 0xc001a08c00?, 0x41057f?}, {0x472a1fe, 0x4}, {0xc002595080, 0x1, 0xc002203450?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0xc001df3aa0?, 0xc001a08c00?, 0x455292?}, {0xc002595080?, 0x46c6b00?, 0x1?})\n\treflect/value.go:368 +0xbc\ngithub.com/traefik/yaegi/interp.call.func9.2({0xc002595080?, 0xc001a08c00?, 0xc001533340?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1301 +0x3c\ngithub.com/traefik/yaegi/interp.call.func9(0xc0025c5760)\n\tgithub.com/traefik/[email protected]/interp/run.go:1326 +0x1265\ngithub.com/traefik/yaegi/interp.runCfg(0xc0012a9e00, 0xc0025c5760, 0x1?, 0x3a3ed60?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc001a08ab0, 0x2, 0x4?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1015 +0x4a5\nreflect.Value.call({0x3b9b6e0?, 0xc001a08a50?, 0x41057f?}, {0x472a1fe, 0x4}, {0xc001a08a80, 0x2, 0xc002203420?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0x3b9b6e0?, 0xc001a08a50?, 0x455292?}, {0xc001a08a80?, 0x46c6b00?, 0x1?})\n\treflect/value.go:368 +0xbc\ngithub.com/traefik/yaegi/interp.call.func9.2({0xc001a08a80?, 0xc001a08a50?, 0xc0015332e0?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1301 +0x3c\ngithub.com/traefik/yaegi/interp.call.func9(0xc0025c5600)\n\tgithub.com/traefik/[email protected]/interp/run.go:1326 +0x1265\ngithub.com/traefik/yaegi/interp.runCfg(0xc001592780, 0xc0025c5600, 0x0?, 0x3a3ed60?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.call.func9(0xc0024e6370)\n\tgithub.com/traefik/[email protected]/interp/run.go:1442 +0x8f9\ngithub.com/traefik/yaegi/interp.runCfg(0xc001560640, 0xc0024e6370, 0x0?, 0x45ac520?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc0019fe600, 0x2, 0x4?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1015 +0x4a5\ngithub.com/traefik/yaegi/stdlib._net_http_Handler.ServeHTTP(...)\n\tgithub.com/traefik/[email protected]/stdlib/go1_19_net_http.go:290\ngithub.com/traefik/traefik/v2/pkg/middlewares/accesslog.(*FieldHandler).ServeHTTP(0xc000245840, {0x52e0cb0, 0xc000efd410}, 0x3c520c0?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/accesslog/field_middleware.go:31 +0x122\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc0026d0000, {0x52e0cb0, 0xc000efd410}, 0xc001b27e00)\n\tgithub.com/gorilla/[email protected]/mux.go:141 +0x24c\ngithub.com/traefik/traefik/v2/pkg/middlewares/recovery.(*recovery).ServeHTTP(0xc001673b80?, {0x52e0cb0?, 0xc000efd410?}, 0x3a38aa0?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/recovery/recovery.go:32 +0x82\ngithub.com/traefik/traefik/v2/pkg/middlewares/accesslog.(*FieldHandler).ServeHTTP(0xc000c9c940, {0x52e0cb0, 0xc000efd410}, 0xc00012c960?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/accesslog/field_middleware.go:31 +0x122\ngithub.com/traefik/traefik/v2/pkg/middlewares/snicheck.SNICheck.ServeHTTP({{0x52a6460?, 0xc000c9c940?}, 0xc0019f3500?}, {0x52e0cb0, 0xc000efd410}, 0xc001b27e00)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/snicheck/snicheck.go:49 +0x189\ngithub.com/traefik/traefik/v2/pkg/middlewares.(*HTTPHandlerSwitcher).ServeHTTP(0x4108c7?, {0x52e0cb0, 0xc000efd410}, 0x529ca01?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/handler_switcher.go:23 +0x62\ngithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator.(*RequestDecorator).ServeHTTP(0xc000efd950, {0x52e0cb0, 0xc000efd410}, 0xc001b27d00, 0xc000d6ab80)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator/request_decorator.go:47 +0x30e\ngithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator.WrapHandler.func1.1({0x52e0cb0?, 0xc000efd410?}, 0xc0019fe450?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator/request_decorator.go:89 +0x68\nnet/http.HandlerFunc.ServeHTTP(0xc000ee8f50?, {0x52e0cb0?, 0xc000efd410?}, 0x9?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders.(*XForwarded).ServeHTTP(0xc000ee8f50, {0x52e0cb0, 0xc000efd410}, 0xc001b27d00)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders/forwarded_header.go:192 +0xca\nnet/http.AllowQuerySemicolons.func1({0x52e0cb0, 0xc000efd410}, 0xc001b27d00)\n\tnet/http/server.go:2974 +0x223\nnet/http.HandlerFunc.ServeHTTP(0x0?, {0x52e0cb0?, 0xc000efd410?}, 0x5?)\n\tnet/http/server.go:2109 +0x2f\nnet/http.serverHandler.ServeHTTP({0x689740?}, {0x52e0cb0, 0xc000efd410}, 0xc001b27d00)\n\tnet/http/server.go:2947 +0x30c\nnet/http.initALPNRequest.ServeHTTP({{0x52ed490?, 0xc0019f6150?}, 0xc000962700?, {0xc0010ae5a0?}}, {0x52e0cb0, 0xc000efd410}, 0xc001b27d00)\n\tnet/http/server.go:3556 +0x245\ngolang.org/x/net/http2.(*serverConn).runHandler(0x7e6a3b8?, 0x0?, 0x0?, 0xc002235680?)\n\tgolang.org/x/[email protected]/http2/server.go:2311 +0x83\ncreated by golang.org/x/net/http2.(*serverConn).processHeaders\n\tgolang.org/x/[email protected]/http2/server.go:2025 +0x64a\n" middlewareName=traefik-internal-recovery middlewareType=Recovery
time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/request.go:50:2: panic" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/bind.go:61:5: panic" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/bind.go:100:3: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/ldapauth.go:232:5: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
time="2023-03-17T12:44:34Z" level=error msg="plugins-storage/sources/gop-3195890994/src/github.com/wiltonsr/ldapAuth/ldapauth.go:125:6: panic" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
time="2023-03-17T12:44:34Z" level=error msg="Recovered from panic in HTTP handler [192.168.32.1:59358 - /favicon.ico]: reflect: Call using int64 as type string" middlewareName=traefik-internal-recovery middlewareType=Recovery
time="2023-03-17T12:44:34Z" level=error msg="Stack: goroutine 106 [running]:\ngithub.com/traefik/traefik/v2/pkg/middlewares/recovery.recoverFunc({0x52e0cb0, 0xc0014cb238}, 0xc002229a00)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/recovery/recovery.go:46 +0x225\npanic({0x3a3ed60, 0xc002024400})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc002024400})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc002024400})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc002024400})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc002024400})\n\truntime/panic.go:884 +0x212\ngithub.com/traefik/yaegi/interp.runCfg.func1()\n\tgithub.com/traefik/[email protected]/interp/run.go:205 +0x13b\npanic({0x3a3ed60, 0xc002024400})\n\truntime/panic.go:884 +0x212\nreflect.Value.call({0x3b06380?, 0xc001a327b0?, 0xc0016afa20?}, {0x472a1fe, 0x4}, {0xc001a327e0, 0x2, 0xc00182f718?})\n\treflect/value.go:440 +0x1abf\nreflect.Value.Call({0x3b06380?, 0xc001a327b0?, 0xc001efd900?}, {0xc001a327e0?, 0xc00182f718?, 0x196?})\n\treflect/value.go:368 +0xbc\ngithub.com/traefik/yaegi/interp.call.func9.2({0xc001a327e0?, 0xc001a327b0?, 0xc001533c00?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1301 +0x3c\ngithub.com/traefik/yaegi/interp.call.func9(0xc0027b3550)\n\tgithub.com/traefik/[email protected]/interp/run.go:1326 +0x1265\ngithub.com/traefik/yaegi/interp.runCfg(0xc001efa280, 0xc0027b3550, 0x2?, 0xc001b95b80?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc0027f4840, 0x1, 0x1?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1015 +0x4a5\nreflect.Value.call({0xc001df3740?, 0xc001a29b30?, 0x41057f?}, {0x472a1fe, 0x4}, {0xc0027f4828, 0x1, 0xc00229aa90?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0xc001df3740?, 0xc001a29b30?, 0x455292?}, {0xc0027f4828?, 0x46c6b00?, 0x1?})\n\treflect/value.go:368 +0xbc\ngithub.com/traefik/yaegi/interp.call.func9.2({0xc0027f4828?, 0xc001a29b30?, 0xc0016ac100?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1301 +0x3c\ngithub.com/traefik/yaegi/interp.call.func9(0xc002753e40)\n\tgithub.com/traefik/[email protected]/interp/run.go:1326 +0x1265\ngithub.com/traefik/yaegi/interp.runCfg(0xc00129de00, 0xc002753e40, 0x2?, 0xc001c04040?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc002750618, 0x1, 0x1?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1015 +0x4a5\nreflect.Value.call({0xc001df3aa0?, 0xc001a1d830?, 0x41057f?}, {0x472a1fe, 0x4}, {0xc002750600, 0x1, 0xc002203450?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0xc001df3aa0?, 0xc001a1d830?, 0x455292?}, {0xc002750600?, 0x46c6b00?, 0x1?})\n\treflect/value.go:368 +0xbc\ngithub.com/traefik/yaegi/interp.call.func9.2({0xc002750600?, 0xc001a1d830?, 0xc001533340?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1301 +0x3c\ngithub.com/traefik/yaegi/interp.call.func9(0xc002753ce0)\n\tgithub.com/traefik/[email protected]/interp/run.go:1326 +0x1265\ngithub.com/traefik/yaegi/interp.runCfg(0xc0012a9e00, 0xc002753ce0, 0x1?, 0x3a3ed60?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc001a1d6e0, 0x2, 0x4?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1015 +0x4a5\nreflect.Value.call({0x3b9b6e0?, 0xc001a1d680?, 0x41057f?}, {0x472a1fe, 0x4}, {0xc001a1d6b0, 0x2, 0xc002203420?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0x3b9b6e0?, 0xc001a1d680?, 0x455292?}, {0xc001a1d6b0?, 0x46c6b00?, 0x1?})\n\treflect/value.go:368 +0xbc\ngithub.com/traefik/yaegi/interp.call.func9.2({0xc001a1d6b0?, 0xc001a1d680?, 0xc0015332e0?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1301 +0x3c\ngithub.com/traefik/yaegi/interp.call.func9(0xc002753b80)\n\tgithub.com/traefik/[email protected]/interp/run.go:1326 +0x1265\ngithub.com/traefik/yaegi/interp.runCfg(0xc001592780, 0xc002753b80, 0x0?, 0x3a3ed60?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.call.func9(0xc002712fd0)\n\tgithub.com/traefik/[email protected]/interp/run.go:1442 +0x8f9\ngithub.com/traefik/yaegi/interp.runCfg(0xc001560640, 0xc002712fd0, 0x0?, 0x45ac520?)\n\tgithub.com/traefik/[email protected]/interp/run.go:213 +0x29d\ngithub.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc001a17bf0, 0x2, 0x4?})\n\tgithub.com/traefik/[email protected]/interp/run.go:1015 +0x4a5\ngithub.com/traefik/yaegi/stdlib._net_http_Handler.ServeHTTP(...)\n\tgithub.com/traefik/[email protected]/stdlib/go1_19_net_http.go:290\ngithub.com/traefik/traefik/v2/pkg/middlewares/accesslog.(*FieldHandler).ServeHTTP(0xc000245840, {0x52e0cb0, 0xc0014cb238}, 0x3c520c0?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/accesslog/field_middleware.go:31 +0x122\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc0026d0000, {0x52e0cb0, 0xc0014cb238}, 0xc002229a00)\n\tgithub.com/gorilla/[email protected]/mux.go:141 +0x24c\ngithub.com/traefik/traefik/v2/pkg/middlewares/recovery.(*recovery).ServeHTTP(0xc0016bb6c0?, {0x52e0cb0?, 0xc0014cb238?}, 0x3a38aa0?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/recovery/recovery.go:32 +0x82\ngithub.com/traefik/traefik/v2/pkg/middlewares/accesslog.(*FieldHandler).ServeHTTP(0xc000c9c940, {0x52e0cb0, 0xc0014cb238}, 0x0?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/accesslog/field_middleware.go:31 +0x122\ngithub.com/traefik/traefik/v2/pkg/middlewares/snicheck.SNICheck.ServeHTTP({{0x52a6460?, 0xc000c9c940?}, 0xc0019f3500?}, {0x52e0cb0, 0xc0014cb238}, 0xc002229a00)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/snicheck/snicheck.go:49 +0x189\ngithub.com/traefik/traefik/v2/pkg/middlewares.(*HTTPHandlerSwitcher).ServeHTTP(0x4108c7?, {0x52e0cb0, 0xc0014cb238}, 0x529ca01?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/handler_switcher.go:23 +0x62\ngithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator.(*RequestDecorator).ServeHTTP(0xc000efd950, {0x52e0cb0, 0xc0014cb238}, 0xc002229800, 0xc001741b80)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator/request_decorator.go:47 +0x30e\ngithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator.WrapHandler.func1.1({0x52e0cb0?, 0xc0014cb238?}, 0xc001a17aa0?)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/requestdecorator/request_decorator.go:89 +0x68\nnet/http.HandlerFunc.ServeHTTP(0xc000ee8f50?, {0x52e0cb0?, 0xc0014cb238?}, 0x9?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders.(*XForwarded).ServeHTTP(0xc000ee8f50, {0x52e0cb0, 0xc0014cb238}, 0xc002229800)\n\tgithub.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders/forwarded_header.go:192 +0xca\nnet/http.AllowQuerySemicolons.func1({0x52e0cb0, 0xc0014cb238}, 0xc002229800)\n\tnet/http/server.go:2974 +0x223\nnet/http.HandlerFunc.ServeHTTP(0x0?, {0x52e0cb0?, 0xc0014cb238?}, 0xc001f1de08?)\n\tnet/http/server.go:2109 +0x2f\nnet/http.serverHandler.ServeHTTP({0x689740?}, {0x52e0cb0, 0xc0014cb238}, 0xc002229800)\n\tnet/http/server.go:2947 +0x30c\nnet/http.initALPNRequest.ServeHTTP({{0x52ed490?, 0xc0019f6150?}, 0xc000962700?, {0xc0010ae5a0?}}, {0x52e0cb0, 0xc0014cb238}, 0xc002229800)\n\tnet/http/server.go:3556 +0x245\ngolang.org/x/net/http2.(*serverConn).runHandler(0x8b2032?, 0x7e6a3b8?, 0x56bf2a?, 0xc002230001?)\n\tgolang.org/x/[email protected]/http2/server.go:2311 +0x83\ncreated by golang.org/x/net/http2.(*serverConn).processHeaders\n\tgolang.org/x/[email protected]/http2/server.go:2025 +0x64a\n" middlewareName=traefik-internal-recovery middlewareType=Recovery

Plugin crash on connection reset.

Sorry for the bad labeling.
I think the overall issue is in our location however it seems like the plugin does not handle it gracefully.

This crashes and restarts traefik. On traefik 2.9.1 and v0.0.20

| ERROR: ldapAuth: 2023/04/19 11:50:43 restricted.go:51: BindDN Error: unable to read LDAP response packet: read tcp 172.18.0.30:37212->10.234.32.10:389: read: connection reset by peer
| ERROR: ldapAuth: 2023/04/19 11:50:43 restricted.go:51: Authentication failed
| ERROR: ldapAuth: 2023/04/19 11:50:43 restricted.go:51: BindDN Error: unable to read LDAP response packet: read tcp 172.18.0.30:37288->10.234.32.10:389: read: connection reset by peer
| ERROR: ldapAuth: 2023/04/19 11:50:43 restricted.go:51: Authentication failed
| time="2023-04-19T11:50:43Z" level=error msg="plugins-storage/sources/gop-1395261136/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/conn.go:65:7: panic" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
| time="2023-04-19T11:50:43Z" level=error msg="plugins-storage/sources/gop-1395261136/src/github.com/wiltonsr/ldapAuth/vendor/github.com/go-ldap/ldap/v3/conn.go:443:13: panic" module=github.com/wiltonsr/ldapAuth plugin=plugin-ldapAuth
| panic: send on closed channel [recovered]
| 	panic: send on closed channel [recovered]
| 	panic: send on closed channel
| 
| goroutine 28171791 [running]:
| github.com/traefik/yaegi/interp.runCfg.func1()
| 	github.com/traefik/[email protected]/interp/run.go:192 +0x148
| panic({0x32d72e0, 0x448f610})
| 	runtime/panic.go:884 +0x212
| github.com/traefik/yaegi/interp.runCfg.func1()
| 	github.com/traefik/[email protected]/interp/run.go:192 +0x148
| panic({0x32d72e0, 0x448f610})
| 	runtime/panic.go:884 +0x212
| reflect.rselect({0xc00396cc78, 0x3, 0x0?})
| 	runtime/select.go:590 +0x23e
| reflect.Select({0xc0007f8f20?, 0x3, 0xc024e39a28?})
| 	reflect/value.go:2952 +0xd2
| github.com/traefik/yaegi/interp._select.func4(0xc008553970)
| 	github.com/traefik/[email protected]/interp/run.go:3760 +0x47e
| github.com/traefik/yaegi/interp.runCfg(0xc00192ad80, 0xc008553970, 0xc00396cf10?, 0xc001f747c0?)
| 	github.com/traefik/[email protected]/interp/run.go:200 +0x29d
| github.com/traefik/yaegi/interp.call.func9(0xc008553550)
| 	github.com/traefik/[email protected]/interp/run.go:1438 +0x965
| github.com/traefik/yaegi/interp.runCfg(0xc0019afc20, 0xc008553550, 0x0?, 0x0?)
| 	github.com/traefik/[email protected]/interp/run.go:200 +0x29d
| github.com/traefik/yaegi/interp.genFunctionWrapper.func2.1({0x63654c0, 0x0, 0x0?})
| 	github.com/traefik/[email protected]/interp/run.go:1022 +0x487
| reflect.Value.call({0x303f140?, 0xc0347d2390?, 0x0?}, {0x39e926c, 0x4}, {0xc01cf6e4e0, 0x0, 0xc0007e8230?})
| 	reflect/value.go:584 +0x8c5
| reflect.Value.Call({0x303f140?, 0xc0347d2390?, 0xc0079bbef8?}, {0xc01cf6e4e0?, 0xc0085533f0?, 0xc002057b70?})
| 	reflect/value.go:368 +0xbc
| github.com/traefik/yaegi/interp.runCfg.func1()
| 	github.com/traefik/[email protected]/interp/run.go:183 +0x1a7
| github.com/traefik/yaegi/interp.runCfg(0xc0019af0e0, 0xc02c4ccfd0, 0xaf25e6?, 0xc0020a77a0?)
| 	github.com/traefik/[email protected]/interp/run.go:202 +0x2f1
| created by github.com/traefik/yaegi/interp.call.func9
| 	github.com/traefik/[email protected]/interp/run.go:1435 +0x91d

[Bug] Apostrophe in user DN fails to match allowed groups

I have a user that has an apostrophe in their last name causing the LDAP filter for group matching to fail. The reason behind it is that the Go templating uses HTML templates and outputs the resulting filter as:

(|(member=CN=First N&#39;ame,OU=Users,OU=Company,DC=test,DC=local)(uniqueMember=CN=First N&#39;ame,OU=Users,OU=Company,DC=test,DC=local)(memberUid=fname))'

The filter should read: (|(member=CN=First N'ame,OU=Users,OU=Company,DC=test,DC=local)(uniqueMember=CN=First N'ame,OU=Users,OU=Company,DC=test,DC=local)(memberUid=fname))'

As per above, the apostrophe (') is escaped to &#39;.

BindDN and BindPassword are not used for AllowedGroups checking

When using the options BindDN and BindPassword in combination with AllowedGroups then the AllowedGroups are checked using the user credentials instead of the bind credentials.

Is this intentional behaviour?

For me this creates an issue since the individual users cannot access group membership information. Only the bind user has access to those parts of the directory.

If it's unintentional, consider this a bug report. If it's intentional, then a feature request for a toggle to choose the behaviour.

Strip comma when baseDN is empty and add option to remove Authorization header before passing to backend

It would be great if the plugin does strip the , from the LDAP-bind if the baseDN is set to "". This would greatly improve compatibility with Active Directory so one could do:

attribute: userPrincipalName (sAMAccountName)
baseDN: ""

Right now this ends results in [email protected], which fails to authenticate.

A nice touch would be the option to remove the Authorization header before passing to the backend, similar to the basicAuth middleware.

Thanks a lot for your consideration.

I don't find syntax for "allowedGroup"

Hello,

Firstly, this plugin is really great. It helped me for my authent with ldap and specially with filtering by username.

Now, I want to integrate my ldap groups. I tried a lot of syntaxes but it's not working.

Here is a example of what I tried with the parameter "allowedGroups":

  • "traefik.http.middlewares.ldap-auth.plugin.ldapAuth.allowedGroups=[cn=MY_GROUP,ou=groups,dc=MY_DOMAIN,dc=fr]"

And thousands others tests...

Please, could you help me ?

Have a nice day.
Raspberry

Plugin fails to load /w Traefik 2.9.4

Testing using Traefik docker images. Attempting to load ldapAuth plugin /w 2.9.4 fails with the following error message. Reverting to 2.9.1 resolves.

level=error msg="plugins-local/src/github.com/wiltonsr/ldapAuth/vendor/golang.org/x/crypto/md4/md4.go:18:2: panic" plugin=plugin-ldapAuth module=github.com/wiltonsr/ldapAuth
panic: reflect: Call using *interp.node as type func() hash.Hash [recovered]
        panic: reflect: Call using *interp.node as type func() hash.Hash
        
goroutine 1 [running]:
github.com/traefik/yaegi/interp.runCfg.func1()
        github.com/traefik/[email protected]/interp/run.go:192 +0x148
panic({0x3a15fc0, 0xc000239e80})
        runtime/panic.go:884 +0x212
reflect.Value.call({0x3a99be0?, 0x4c28f48?, 0x41057f?}, {0x46f126c, 0x4}, {0xc00187c0f0, 0x2, 0xf2ac3357f0?})
        reflect/value.go:440 +0x1abf
reflect.Value.Call({0x3a99be0?, 0x4c28f48?, 0x455252?}, {0xc00187c0f0?, 0x468dba0?, 0xc0005c8790?})
        reflect/value.go:368 +0xbc
github.com/traefik/yaegi/interp.callBin.func2({0x3a99be0?, 0x4c28f48?, 0x4048f4?}, {0xc00187c0f0?, 0xc001b37470?, 0x393d1e0?})
        github.com/traefik/[email protected]/interp/run.go:1483 +0x28
github.com/traefik/yaegi/interp.callBin.func11(0xc0005c8790)
        github.com/traefik/[email protected]/interp/run.go:1658 +0x15f
github.com/traefik/yaegi/interp.runCfg(0xc000852a20, 0xc0005c8790, 0x8?, 0x6?)
        github.com/traefik/[email protected]/interp/run.go:200 +0x29d
github.com/traefik/yaegi/interp.(*Interpreter).run(0xc000d27680, 0xc000852000, 0xc0005c8420?)
        github.com/traefik/[email protected]/interp/run.go:119 +0x38e
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc000d27680, {0xc000828000, 0x3f}, {0xc001bce641, 0x17}, 0x1)
        github.com/traefik/[email protected]/interp/src.go:168 +0xb4f
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc001c78a20)
        github.com/traefik/[email protected]/interp/gta.go:262 +0x20be
github.com/traefik/yaegi/interp.(*node).Walk(0xc001c78a20, 0xc001d1c580, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:284 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc001c78480, 0xc001d1c580, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:288 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc001c78240, 0xc001d1c580, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:288 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc000d27680, 0xc001c78240, {0xc000828000, 0x3f}, {0xc00124d961, 0x1b}, {0xc001a332e0, 0x7})
        github.com/traefik/[email protected]/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc000d27680, {0xc001746e40, 0x3e}, {0xc00124d961, 0x1b}, 0x1)
        github.com/traefik/[email protected]/interp/src.go:108 +0x100f
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc001a4d320)
        github.com/traefik/[email protected]/interp/gta.go:262 +0x20be
github.com/traefik/yaegi/interp.(*node).Walk(0xc001a4d320, 0xc001d1d358, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:284 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc0019e9e60, 0xc001d1d358, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:288 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc0019e9c20, 0xc001d1d358, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:288 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc000d27680, 0xc0019e9c20, {0xc001746e40, 0x3e}, {0xc000293e61, 0x1a}, {0xc001264740, 0x4})
        github.com/traefik/[email protected]/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc000d27680, {0xc00124c100, 0x1c}, {0xc000293e61, 0x1a}, 0x1)
        github.com/traefik/[email protected]/interp/src.go:108 +0x100f
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc00126c5a0)
        github.com/traefik/[email protected]/interp/gta.go:262 +0x20be
github.com/traefik/yaegi/interp.(*node).Walk(0xc00126c5a0, 0xc001d1e130, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:284 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc00126a000, 0xc001d1e130, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:288 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc000ecfd40, 0xc001d1e130, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:288 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc000d27680, 0xc000ecfd40, {0xc00124c100, 0x1c}, {0xc000293d81, 0x1c}, {0xc000d2a940, 0x8})
        github.com/traefik/[email protected]/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc000d27680, {0xc000d2a810, 0x4}, {0xc000293d81, 0x1c}, 0x1)
        github.com/traefik/[email protected]/interp/src.go:108 +0x100f
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc000ecfb00)
        github.com/traefik/[email protected]/interp/gta.go:262 +0x20be
github.com/traefik/yaegi/interp.(*node).Walk(0xc000ecfb00, 0xc001d1ef08, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:284 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc000ecf9e0, 0xc001d1ef08, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:288 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc000ecf7a0, 0xc001d1ef08, 0x0)
        github.com/traefik/[email protected]/interp/interp.go:288 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc000d27680, 0xc000ecf7a0, {0xc000d2a810, 0x4}, {0xc000d2a810, 0x4}, {0xc000d2a810, 0x4})
        github.com/traefik/[email protected]/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).gtaRetry(0xc000d27680?, {0xc0014fb0e8?, 0xc001114080?, 0xc0014fb030?}, {0xc000d2a810, 0x4}, {0xc000d2a810, 0x4})
        github.com/traefik/[email protected]/interp/gta.go:384 +0x154
github.com/traefik/yaegi/interp.(*Interpreter).CompileAST(0xc000d27680, {0x5287508?, 0xc001114080?})
        github.com/traefik/[email protected]/interp/program.go:87 +0x17f
github.com/traefik/yaegi/interp.(*Interpreter).compileSrc(0xc000d27680, {0xc00062bf50?, 0x1?}, {0x0?, 0xc00062bf50?}, 0xe0?)
        github.com/traefik/[email protected]/interp/program.go:59 +0xb8
github.com/traefik/yaegi/interp.(*Interpreter).eval(0xc000d27680, {0xc00062bf50?, 0xc0014fb358?}, {0x0?, 0x1?}, 0x0?)
        github.com/traefik/[email protected]/interp/interp.go:552 +0x28
github.com/traefik/yaegi/interp.(*Interpreter).Eval(...)
        github.com/traefik/[email protected]/interp/interp.go:494
github.com/traefik/traefik/v2/pkg/plugins.NewBuilder(0x0, 0x0?, 0xc000b36898?)
        github.com/traefik/traefik/v2/pkg/plugins/builder.go:104 +0xdc6
main.createPluginBuilder(0xc000582cf0?)
        github.com/traefik/traefik/v2/cmd/traefik/plugins.go:18 +0x35
main.setupServer(0xc000582cf0)
        github.com/traefik/traefik/v2/cmd/traefik/traefik.go:211 +0x538
main.runCmd(0xc000582cf0)
        github.com/traefik/traefik/v2/cmd/traefik/traefik.go:118 +0x3df
main.main.func1({0xc00111a320?, 0xc00013a020?, 0x8?})
        github.com/traefik/traefik/v2/cmd/traefik/traefik.go:63 +0x1f
github.com/traefik/paerser/cli.run(0xc000655780, {0xc00013a020?, 0xa?, 0xa?})
        github.com/traefik/[email protected]/cli/commands.go:133 +0x193
github.com/traefik/paerser/cli.execute(0xc000655780, {0xc00013a000?, 0xc, 0xc}, 0x78?)
        github.com/traefik/[email protected]/cli/commands.go:76 +0x74a
github.com/traefik/paerser/cli.Execute(...)
        github.com/traefik/[email protected]/cli/commands.go:51
main.main()
        github.com/traefik/traefik/v2/cmd/traefik/traefik.go:79 +0x405

User DN format question

I'm just starting with this great plugin but have a question.
The DN format when querying is uid=USERNAME,dn=example,dn=com
but my LDAP server requires uid=USERNAME,cn=user,dn=example,dn=com
is there a way to manipulate the query sting to support the server please?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.