{"id":15575599,"url":"https://github.com/wiltonsr/ldapauth","last_synced_at":"2025-04-05T13:06:51.826Z","repository":{"id":44885701,"uuid":"411377614","full_name":"wiltonsr/ldapAuth","owner":"wiltonsr","description":"An open source Traefik Middleware that enables authentication via LDAP in a similar way to Traefik Enterprise","archived":false,"fork":false,"pushed_at":"2024-11-26T15:13:14.000Z","size":536,"stargazers_count":121,"open_issues_count":5,"forks_count":13,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-29T12:09:25.774Z","etag":null,"topics":["authentication","authentication-middleware","gandalpher","go","go-ldap","golang","hacktoberfest","ldap","ldap-authentication","plugin","traefik-middleware","traefik-plugin","traefik-v2"],"latest_commit_sha":null,"homepage":"https://plugins.traefik.io/plugins/628c9eb7ffc0cd18356a979c/ldap-auth","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wiltonsr.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://www.paypal.com/donate/?cmd=_donations\u0026business=5QJ62BNMRC75W\u0026currency_code=USD\u0026source=url"]}},"created_at":"2021-09-28T17:26:52.000Z","updated_at":"2025-03-22T00:30:54.000Z","dependencies_parsed_at":"2023-11-23T13:43:12.192Z","dependency_job_id":"ab86e00e-6b3b-4a13-9593-f5e1f831a059","html_url":"https://github.com/wiltonsr/ldapAuth","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":"traefik/plugindemo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiltonsr%2FldapAuth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiltonsr%2FldapAuth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiltonsr%2FldapAuth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiltonsr%2FldapAuth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wiltonsr","download_url":"https://codeload.github.com/wiltonsr/ldapAuth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339155,"owners_count":20923014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","authentication-middleware","gandalpher","go","go-ldap","golang","hacktoberfest","ldap","ldap-authentication","plugin","traefik-middleware","traefik-plugin","traefik-v2"],"created_at":"2024-10-02T18:39:19.928Z","updated_at":"2025-04-05T13:06:51.801Z","avatar_url":"https://github.com/wiltonsr.png","language":"Go","funding_links":["https://www.paypal.com/donate/?cmd=_donations\u0026business=5QJ62BNMRC75W\u0026currency_code=USD\u0026source=url"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/wiltonsr/ldapAuth/raw/main/imgs/gandalpher.png\" alt=\"Gandalpher\" title=\"Gandalpher\" /\u003e\n\u003cbr\u003e\n\u003cem\u003e\u003cb\u003e\"You shall authenticate to the LDAP to pass\"\u003c/b\u003e - Gandalpher, the gopher\u003c/em\u003e\n\u003c/p\u003e\n\n---\n\n\u003ch1 align=\"center\"\u003e\n\u003cimg alt=\"GitHub\" src=\"https://img.shields.io/github/license/wiltonsr/ldapAuth?color=blue\"\u003e\n\u003cimg alt=\"GitHub release (latest by date including pre-releases)\" src=\"https://img.shields.io/github/v/release/wiltonsr/ldapAuth?include_prereleases\"\u003e\n\u003cimg alt=\"GitHub go.mod Go version\" src=\"https://img.shields.io/github/go-mod/go-version/wiltonsr/ldapAuth\"\u003e\n\u003cimg alt=\"GitHub issues\" src=\"https://img.shields.io/github/issues/wiltonsr/ldapAuth\"\u003e\n\u003cimg alt=\"GitHub last commit (branch)\" src=\"https://img.shields.io/github/last-commit/wiltonsr/ldapAuth/main\"\u003e\n\u003c/h1\u003e\n\n# Traefik ldapAuth Middleware\n\nThis project is an in-progress effort to create an open-source middleware that enables authentication via LDAP in a similar way to [Traefik Enterprise](https://doc.traefik.io/traefik-enterprise/middlewares/ldap/).\n\n## Requirements\n\n- Traefik \u003e= [v2.10.0](https://github.com/traefik/traefik/releases/tag/v2.5.5)\n\n[Traefik](https://traefik.io) plugins are developed using the compiled [Go language](https://golang.org). Rather than being pre-compiled and linked, however, plugins are executed on the fly by [Yaegi](https://github.com/traefik/yaegi), an embedded Go interpreter. Due to [traefik/yaegi#1275](https://github.com/traefik/yaegi/issues/1275) and [traefik/yaegi#1484](https://github.com/traefik/yaegi/issues/1484), the `ldap-go` module only works after the listed version.\n\n## Usage\n\n### Add Plugin to Service\n\n```yml\nwhoami:\n  image: \"traefik/whoami\"\n  container_name: \"whoami\"\n  labels:\n    - traefik.enable=true\n    - traefik.http.routers.whoami.rule=Host(`whoami.localhost`)\n    - traefik.http.routers.whoami.entrypoints=web\n    # ldapAuth Register Middleware ====================================================\n    - traefik.http.routers.whoami.middlewares=ldap_auth\n    # ldapAuth Options=================================================================\n    - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.enabled=true\n    - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.logLevel=DEBUG\n    - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.attribute=uid\n    - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.baseDN=dc=example,dc=com\n    - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].url=ldap://ldap.forumsys.com\n    - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].port=389\n    # =================================================================================\n```\n\n### Bind Mode Example\n\n```yml\n[...]\nlabels:\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.attribute=uid\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.baseDN=dc=example,dc=com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].url=ldap://ldap.forumsys.com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].port=389\n```\n\n### Search Mode Anonymous Example\n\n```yml\n[...]\nlabels:\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.attribute=uid\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.baseDN=dc=example,dc=com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.searchFilter=({{.Attribute}}={{.Username}})\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].url=ldap://ldap.forumsys.com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].port=389\n```\n\n### Search Mode Authenticated Example\n\n```yml\n[...]\nlabels:\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.attribute=uid\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.baseDN=dc=example,dc=com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.bindDN=uid=tesla,dc=example,dc=com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.bindPassword=password\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.searchFilter=({{.Attribute}}={{.Username}})\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].url=ldap://ldap.forumsys.com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].port=389\n```\n\n### Advanced Search Mode Example\n\n```yml\n[...]\nlabels:\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.attribute=uid\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.baseDN=dc=example,dc=com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.bindDN=uid=tesla,dc=example,dc=com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.bindPassword=password\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.searchFilter=(\u0026(objectClass=person)({{.Attribute}}={{.Username}}))\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].url=ldap://ldap.forumsys.com\n  - traefik.http.middlewares.ldap_auth.plugin.ldapAuth.serverList[0].port=389\n```\n\n## Operations Mode\n\nThe `Operation Mode` detected will be used to perform all subsequent requests.\n\n### Bind Mode\n\nIf no `searchFilter` is specified in its configuration, the middleware runs in the default bind mode, meaning it tries to make a simple bind request to the LDAP server with the credentials provided in the request headers. If the bind succeeds, the middleware forwards the request, otherwise, it returns a 401 Unauthorized status code.\n\n### Search Mode\n\nIf a `searchFilter` query is specified in the configuration, then the middleware runs in search mode. In this mode, a search query with the given filter is issued to the LDAP server before trying to bind. If `bindDN` and `bindPassword` have also been provided, then the search query will use these credentials. If the result of this search returns only `1` record, it tries to issue a bind request with this record, otherwise, it aborts a 401 Unauthorized status code.\n\n## Options\n\n##### `enabled`\n\n_Optional, Default: `true`_\n\nControls whether requests will be checked against LDAP or not before being delivered.\n\n##### `logLevel`\n\n_Optional, Default: `INFO`_\n\nSet `LogLevel` for detailed information about plugin operation.\n\n##### `serverList.url`\n\n_Required, Default: `\"\"`_\n\nLDAP server address where queries will be performed.\n\n##### `serverList.port`\n\n_Required, Default: `389`_\n\nLDAP server port where queries will be performed.\n\n##### `serverList.weight`\n\n_Optional, Default: `0`_\n\nLDAP server weight to sort `serverList`. Higher weight, higher precedence.\n\n##### `cacheTimeout`\n_Optional, Default: `300`_\n\nIndicates the number of `seconds` until the session cookie expires. A zero or negative number will expire the cookie immediately. \n\n##### `cacheCookieName`\n_Optional, Default: `ldapAuth_session_token`_\n\nThe session cookie name.\n\n##### `cacheCookiePath`\n_Optional, Default: `\"\"`_\n\nThe session cookie path. By default, the cookie path will be set to the request path.\n\n##### `cacheCookieSecure`\n_Optional, Default: `false`_\n\nSet to true if the session cookie should have the secure flag. The cookie will only be transmitted over an HTTPS connection.\n\n##### `cacheKey`\nNeeds `traefik` \u003e= [`v2.8.5`](https://github.com/traefik/traefik/releases/tag/v2.8.5)\n\n_Optional_\n\nThe key used to sign session cookie information. If unset, one will be randomly generated at startup.\n\n##### `serverList.startTLS`\n_Optional, Default: `false`_\n\nIf set to true, instruct `ldapAuth` to issue a `StartTLS` request when initializing the connection with the LDAP server.\n\n##### `serverList.insecureSkipVerify`\n_Optional, Default: `false`_\n\nWhen connecting to a `ldaps` server or `startTLS` is enabled, the connection to the LDAP server is verified to be secure. This option allows `ldapAuth` to proceed and operate even for server connections otherwise considered insecure.\n\n##### `serverList.minVersionTLS`\n_Optional, Default: `tls.VersionTLS12`_\n\nContains the minimum TLS version that is acceptable. By default, `TLS 1.2` is currently used as the minimum. `TLS 1.0` is the minimum supported by this package.\n\nThis option value must match [crypto/tls](https://pkg.go.dev/crypto/tls#pkg-constants) versions constants.\n\n##### `serverList.maxVersionTLS`\n_Optional, Default: `tls.VersionTLS13`_\n\nContains the maximum TLS version that is acceptable. By default, the maximum version supported by this package is used, which is currently `TLS 1.3`.\n\nThis option value must match [crypto/tls](https://pkg.go.dev/crypto/tls#pkg-constants) versions constants.\n\n##### `serverList.certificateAuthority`\n_Optional, Default: `\"\"`_\n\nThe `serverList.certificateAuthority` option should contain one or more PEM-encoded certificates to use to establish a connection with the LDAP server if the connection uses TLS but the certificate was signed by a custom Certificate Authority.\n\n\nExample:\n```yml\n    ServerList:\n        CertificateAuthority: |-\n            -----BEGIN CERTIFICATE-----\n            MIIB9TCCAWACAQAwgbgxGTAXBgNVBAoMEFF1b1ZhZGlzIExpbWl0ZWQxHDAaBgNV\n            BAsME0RvY3VtZW50IERlcGFydG1lbnQxOTA3BgNVBAMMMFdoeSBhcmUgeW91IGRl\n            Y29kaW5nIG1lPyAgVGhpcyBpcyBvbmx5IGEgdGVzdCEhITERMA8GA1UEBwwISGFt\n            aWx0b24xETAPBgNVBAgMCFBlbWJyb2tlMQswCQYDVQQGEwJCTTEPMA0GCSqGSIb3\n            DQEJARYAMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ9WRanG/fUvcfKiGl\n            EL4aRLjGt537mZ28UU9/3eiJeJznNSOuNLnF+hmabAu7H0LT4K7EdqfF+XUZW/2j\n            RKRYcvOUDGF9A7OjW7UfKk1In3+6QDCi7X34RE161jqoaJjrm/T18TOKcgkkhRzE\n            apQnIDm0Ea/HVzX/PiSOGuertwIDAQABMAsGCSqGSIb3DQEBBQOBgQBzMJdAV4QP\n            Awel8LzGx5uMOshezF/KfP67wJ93UW+N7zXY6AwPgoLj4Kjw+WtU684JL8Dtr9FX\n            ozakE+8p06BpxegR4BR3FMHf6p+0jQxUEAkAyb/mVgm66TyghDGC6/YkiKoZptXQ\n            98TwDIK/39WEB/V607As+KoYazQG8drorw==\n            -----END CERTIFICATE-----\n```\n\n##### `attribute`\n\n_Optional, Default: `cn`_\n\nThe attribute used to bind a user in [`Bind Mode`](#bind-mode). Bind queries use this pattern: `\u003cattribute\u003e=\u003cusername\u003e,\u003cbaseDN\u003e`, where the username is extracted from the request header. If [`AllowedGroups`](#allowedGroups) option was used in [`Bind Mode`](#bind-mode), the same pattern is added when searching if the user belongs to the group.\n\n##### `searchFilter`\n\n_Optional, Default: `\"\"`_\n\nIf not empty, the middleware will run in [`Search Mode`](#search-mode), filtering search results with the given query.\n\nFilter queries can use the `{{.Option}}` format, from [text/template](https://pkg.go.dev/text/template#pkg-overview) go package, as placeholders that are replaced by the equivalent value from config. Additionally, the username provided in the Authorization header of the request can also be used.\n\nFor example: `(\u0026(objectClass=inetOrgPerson)(gidNumber=500)({{.Attribute}}={{.Username}}))`.\n\nWill be replaced to: `(\u0026(objectClass=inetOrgPerson)(gidNumber=500)(uid=tesla))`.\n\nNote1: All filter options must start with Uppercase to be replaced correctly.\n\nNote2: `searchFilter` must **not** escape curly braces when using [labels](examples/conf-from-labels.yml).\n\nNote3: `searchFilter` must escape curly braces when using [yml file](examples/dynamic-conf/ldapAuth-conf.yml).\n\nNote4: `searchFilter` must escape curly braces when using [toml file](examples/dynamic-conf/ldapAuth-conf.toml).\n\n##### `baseDN`\n\n_Required, Default: `\"\"`_\n\nFrom where the plugin will search for users.\n\n##### `bindDN`\n\n_Optional, Default: `\"\"`_\n\nThe domain name to bind to in order to authenticate to the LDAP server when running on [`Search Mode`](#search-mode). Leaving this empty with [`Search Mode`](#search-mode) means binds are anonymous, which is rarely expected behavior. It is not used when running in [`Bind Mode`](#bind-mode).\n\n##### `bindPassword`\n\n_Optional, Default: `\"\"`_\n\nThe password corresponding to the `bindDN` specified when running in [`Search Mode`](#search-mode), is used in order to authenticate to the LDAP server.\n\n##### `forwardUsername`\n\n_Optional, Default: `true`_\n\nThe `forwardUsername` option can be enabled to forward the username in a specific header, defined using the `forwardUsernameHeader` option.\n\n##### `forwardUsernameHeader`\n\n_Optional, Default: `Username`_\n\nName of the header to put the username in when forwarding it. This is not used if the `forwardUsername` option is set to `false`.\n\n##### `forwardAuthorization`\n\n_Optional, Default: `false`_\n\nThe `forwardAuthorization` option determines if the authorization header will be forwarded or stripped from the request after the middleware has approved it. `Attention`, enabling this option may expose the password of the LDAP user who is making the request.\n\n##### `forwardExtraLDAPHeaders`\n\n_Optional, Default: `false`_\n\nThe `forwardExtraLDAPHeaders` option determines if the LDAP Extra Headers, `Ldap-Extra-Attr-DN` and\n`Ldap-Extra-Attr-CN`, will be added or not to request. This is not used if the `forwardUsername` option is set to `false` or if `searchFilter` is empty.\n\n##### `wwwAuthenticateHeader`\n\n_Optional, Default: `true`_\n\nIf the LDAP middleware receives a request with a missing or invalid Authorization header and `wwwAuthenticateHeader` is enabled, it will set a `WWW-Authenticate` header in the 401 Unauthorized response. See the [WWW-Authenticate header documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate) for more information.\n\n##### `wwwAuthenticateHeaderRealm`\n\n_Optional, Default: `\"\"`_\n\nThe name of the realm to specify in the `WWW-Authenticate` header. This option is ineffective unless the `wwwAuthenticateHeader` option is set to true.\n\n##### `enableNestedGroupFilter`\n\n_Optional, Default: `false`_\n\nIf you need to search the user's nested group and the `LDAP` server support to [search for LDAP_MATCHING_RULE_IN_CHAIN groups](https://ldapwiki.com/wiki/Wiki.jsp?page=LDAP_MATCHING_RULE_IN_CHAIN), you can enabled it by settings this parameter to `true`, it is disabled by default.\n\n##### `allowedGroups`\nNeeds `traefik` \u003e= [`v2.8.2`](https://github.com/traefik/traefik/releases/tag/v2.8.2)\n\n_Optional, Default: `[]`_\n\nThe list of LDAP group DNs that users must be members of to be granted access. If a user is in any of the listed groups, then that user is granted access.\n\nIf set to an empty list, all users with an LDAP account can log in, without performing any group membership checks unless `allowedUsers` is set. In that case, the user must be a part of the `allowedUsers` list.\n\n`allowedGroups` is not supported with labels, because multiple value labels are separated with commas. You must use `toml` or `yaml` configuration file. For more details, check [examples](https://github.com/wiltonsr/ldapAuth/tree/main/examples) page.\n\n##### `allowedUsers`\nNeeds `traefik` \u003e= [`v2.8.2`](https://github.com/traefik/traefik/releases/tag/v2.8.2)\n\n_Optional, Default: `[]`_\n\nThe list of LDAP user DNs or usernames to be granted access. If a user is in the listed users, then that user is granted access.\n\nIf set to an empty list, all users with an LDAP account can log in, unless `allowedGroups` is set. In that case, group membership checks will be performed.\n\n`allowedUsers` is not supported with labels, because multiple value labels are separated with commas. You must use `toml` or `yaml` configuration file. For more details, check [examples](https://github.com/wiltonsr/ldapAuth/tree/main/examples) page.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwiltonsr%2Fldapauth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwiltonsr%2Fldapauth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwiltonsr%2Fldapauth/lists"}