A project to register users via a registration link directly into a directory service. Both Microsoft Active Directory and standard LDAP servers (e.g. OpenLDAP, 389 Directory Server) are supported. The directory backend is selected during installation through the .env configuration; Active Directory is prioritized and used as the default when no explicit value is provided.
The project consists of two components:
- Admin App: Allows an administrator to generate an invitation link and send it to a user by email. An administrator can approve or reject users who registered via a link, manage existing groups and inspect group/user membership. This app should only be available on the internal network and must not be exposed to the internet.
- Registration App: A user can register themselves via a link generated by the admin app. This app is designed to be exposed to the internet.
- A computer, VM or server that can run Docker.
- Docker and Docker Compose set up.
- A reverse proxy to provide TLS for the apps. The apps do not manage TLS certificates themselves and are designed to run behind a reverse proxy.
- Firewall rules to allow the registration app to be available from outside the network if you want users to register via the Internet.
- Reachable Active Directory or LDAP server with a service account that can create users and modify group membership.
Download the compose.yml and the .env file, configure the variables inside the .env file and run docker compose up -d to start.
curl -O https://raw.githubusercontent.com/we-kode/adreg/master/compose.yml
curl -O https://raw.githubusercontent.com/we-kode/adreg/master/.env
This project integrates with Active Directory or with a standard LDAP server (e.g. OpenLDAP, 389 Directory Server). The Admin app uses the configured connection to create users, list groups and add new accounts to selected groups.
If you are using Active Directory with LDAPS, see LDAPS troubleshooting for detailed troubleshooting steps and recommended Docker configuration.
Active Directory is prioritized: if AD__ServerType is omitted or set to an unknown value, the app behaves as if ActiveDirectory was selected. Only set AD__ServerType=Ldap to switch to a generic LDAP profile.
| Setting | Description |
|---|---|
AD__ServerType |
ActiveDirectory (default) or Ldap. Selects attribute names, object classes, password handling and account-enable rules. |
AD__LdapUrl |
LDAP/LDAPS URL or host:port. Examples: ldaps://dc01.example.local:636, ldap://openldap.example.org:389. |
AD__BindDn |
DN of the service account used to bind. Must have permission to create users and modify group membership. |
AD__BindPassword |
Password of the bind account. |
AD__SearchBase |
Base DN for searches, e.g. DC=example,DC=local or dc=example,dc=org. |
AD__UsersContainer |
OU/container for new users. Relative to SearchBase (e.g. OU=Users) or a full DN. |
AD__GroupsContainer |
Optional OU/container for groups. Relative or full DN. Falls back to SearchBase. |
AD__UsersObjectClasses |
Optional comma-separated object classes treated as users. Defaults to user (AD) or inetOrgPerson (LDAP). |
AD__GroupsObjectClasses |
Optional comma-separated object classes treated as groups. Defaults to group (AD) or groupOfNames (LDAP). |
AD__UsernameAttribute |
Optional override for the username attribute. Defaults to sAMAccountName (AD) or uid (LDAP). |
AD__InvitationSenderEmail |
Optional. If set, written to the user's mail attribute instead of the user's own address. |
AD__AllowInvalidCertificate |
If true, the LDAP server certificate is not validated. Use only for testing. |
AD__ServerType=ActiveDirectory
AD__LdapUrl=ldaps://dc01.example.local:636
AD__BindDn=CN=adregsvc,OU=Service Accounts,DC=example,DC=local
AD__BindPassword=VerySecretPassword123!
AD__SearchBase=DC=example,DC=local
AD__UsersContainer=OU=Users
AD__GroupsContainer=OU=Groups
AD__AllowInvalidCertificate=false
AD__ServerType=Ldap
AD__LdapUrl=ldap://openldap.example.org:389
AD__BindDn=cn=admin,dc=example,dc=org
AD__BindPassword=admin
AD__SearchBase=dc=example,dc=org
AD__UsersContainer=ou=users,dc=example,dc=org
AD__GroupsContainer=ou=groups,dc=example,dc=org
AD__UsersObjectClasses=inetOrgPerson
AD__GroupsObjectClasses=groupOfNames
AD__AllowInvalidCertificate=false
- If a container value contains both
=and,it is treated as a full DN; otherwise it is appended toSearchBase. - Group references in registration links may be either the full group DN or the bare
cn. The latter is resolved by searchingGroupsContainer. - For Active Directory, setting
unicodePwdtypically requires LDAPS. Without LDAPS, the account is created but the password attempt is logged as a warning - set the password manually afterwards. - For OpenLDAP, the password is written to
userPassword. Configure your password policy to hash on the fly, or pre-hash if your deployment requires it. - On Active Directory, group membership for a user is read via the
memberOfback-link. On LDAP servers without thememberofoverlay, membership is resolved by reading the group'smemberattribute - both directions work out of the box. - New
groupOfNamesentries on standard LDAP require at least one member; the bind DN is used as the seed when creating a group through the admin UI. - Errors raised by the directory backend are caught and surfaced in the Admin UI as alerts. The app does not crash on transient connectivity or schema problems. AJAX endpoints return HTTP 503 with a JSON
errorfield that the UI displays inline.
- On the target users OU:
Create Child Objects(or Create User). - On groups:
Write Members(ability to modify thememberattribute). - For password operations on AD via LDAPS: LDAPS must be correctly configured on the DC (certificate trusted by the client).
- Verify the LDAP/LDAPS endpoint is reachable (e.g.
openssl s_client -connect dc01.example.local:636). - Verify the bind account DN and password.
- Verify
SearchBasematches the directory root. - Verify
UsersContainerexists and the bind account can create entries there. - Verify groups are visible and searchable via
cn.
Get-ADDomain | Select-Object DistinguishedName
Get-ADUser -Identity adregsvc | Select-Object DistinguishedName
Get-ADGroup -Filter * | Select-Object Name, DistinguishedName
- Configure the variables for the SMTP server and the directory backend (see examples above).
- Optional values can be adjusted as needed.
- Start the apps. The admin app runs by default on port 8081 and the registration app on port 8082.
- Groups are listed by their common name (
cn), sorted alphabetically. - Users are listed as
Lastname, Firstname (Username), sorted alphabetically. If first or last name is missing, the entry falls back to the display name, username, mail orcn. - Failures while reading from or writing to the directory are surfaced as alerts in the UI; they are not allowed to crash the app. Server-side error messages are bubbled up to the Admin view (TempData alerts and inline AJAX error banners) so the operator sees the underlying cause.