You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- `identity.ldap.servers.name`: A name that only exists in `authgear.yaml` and `authgear.secrets.yaml` for associating a LDAP server. It serves no other purpose.
61
+
- `identity.ldap.servers.name`: A unique name to identify this LDAP server. Once set, it cannot be changed. It is stored in the database as part of the unique key to identify a LDAP identity. See [The database schema of a LDAP identity](#the-database-schema-of-a-ldap-identity) for details.
57
62
- `identity.ldap.servers.url`: The connection URL to the LDAP server. The scheme MUST be `ldap:` or `ldaps:`. The URL MUST contain `host`, and optionally a port. If the port is omitted, the default port of the scheme is assumed. The default port of `ldap:` is `389`, while the default port of `ldaps:` is `636`. The URL MUST NOT contain other elements, such as path, nor query.
63
+
- `identity.ldap.servers.base_dn`: The base DN to construct a Search Request, as defined in [Section 4.5.1 in RFC4511](https://datatracker.ietf.org/doc/html/rfc4511#section-4.5.1).
64
+
- `identity.ldap.servers.search_filter_template`: A Go template that renders to a filter to be used in the Search Request. This template can use the variable `$.Username` to render the username entered by the end-user. `$.Username` is pre-processed so that it is an escaped LDAP string. The strings function from [https://masterminds.github.io/sprig/](https://masterminds.github.io/sprig/) can be used in the template.
65
+
- `identity.ldap.servers.user_id_attribute`: The attribute that is guaranteed to be unique and never change for a given user in the LDAP server. It is used to identify a user from the LDAP server. Warning: Changing this value will cause Authgear not able to look up any previous LDAP identities.
58
66
59
67
> Why does `identity.ldap.servers.url` allow scheme, host, and port?
60
68
> The LDAP URL, defined in [Section 2 in RFC 4516](https://datatracker.ietf.org/doc/html/rfc4516#section-2), is syntactically different from the URL defined in [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986).
61
69
> In particular, a LDAP URL can contain multiple question mark characters.
62
70
> To ease implementation, we do not support the LDAP URL, and require a RFC3986 URL (which is implemented by the standard library net/url package).
63
71
64
-
- `identity.ldap.servers.base_distinguished_name`: The base distinguished name to construct a Search Request, as defined in [Section 4.5.1 in RFC4511](https://datatracker.ietf.org/doc/html/rfc4511#section-4.5.1).
65
-
- `identity.ldap.servers.relative_distinguished_name_attribute`: The attribute name Authgear should use to construct the search request. For example, if the value is `uid`, and the end-user gives a username of `user1`, and the base distinguished name is `dc=example,dc=com`, then the relative distinguished name is `uid=user1`, and the distinguished name is `uid=user1,dc=example,dc=com`.
66
-
67
-
> base_distinguished_name and relative_distinguished_name_attribute may not be sufficient if the developer needs to determine the DN in a more dynamic way.
68
-
> In the future, we can support a new configuration, distinguished_name_template, which is a Go template that MUST return a DN.
69
-
> It looks like
70
-
> ```
71
-
> {{- if (hasSuffix $.Username "@mycompany.com") }}
> TODO: The current configuration is missing an important feature. The feature is allow the developer to specify what attributes they want to retrieve from the LDAP server, and
79
73
> what attributes map to which standard attributes.
80
74
@@ -84,45 +78,92 @@ In `authgear.secrets.yaml`
84
78
secrets:
85
79
- data:
86
80
items:
87
-
- name: ldap1
81
+
- name: default
88
82
username: authgear
89
83
password: secret1
90
-
- name: ldap2
91
-
username: authgear
92
-
password: secret2
93
84
key: ldap
94
85
```
95
86
96
87
- `items.name`: To associate a LDAP server in `authgear.yaml`.
97
88
- `items.username`: Optional. The username Authgear uses to authenticate itself to the LDAP server. If it is not provided, then Authgear does not authenticates itself, and assumes the LDAP server allows anonymous requests.
98
89
- `items.password`: Optional. The password Authgear uses to authenticate itself to the LDAP server. If `username` is provided, then `password` is required.
99
90
91
+
## Validation on the configuration
92
+
93
+
Here is the JSON schema for the LDAP server configuration.
- `format: ldap_url`: It is a JSON schema format that implements the rules of `identity.ldap.servers.url`.
126
+
- `format: ldap_dn`: It is a JSON schema format that validates the value to be a valid DN.
127
+
- `format: ldap_search_filter_template`: It is a JSON schema format that validates the rendered string to be a valid Search Filter. It does the validation by running the template with `Username=user`, `Username=user@example.com`, and `Username=+85298765432`, and then parse the resulting Search Filter as a Search Filter.
128
+
- `format: ldap_attribute_name`: It is a JSON schema format that validates the value to be a valid LDAP attribute name.
129
+
130
+
## Testing on the configuration
131
+
132
+
> TODO: Add a mutation in the Admin API to test LDAP connection.
133
+
> It should take the whole server configuration, and optionally a end-user username.
134
+
> It connects the LDAP server with the URL and the credentials.
135
+
> If the optional end-user username is given, it performs a Search request, and validates the user exists and has user_id_attribute.
136
+
> It returns detailed API errors so that the portal can display relevant information for the developer to debug the configuration.
137
+
> Such detailed API errors ARE NOT returned in actual use. They are reported as internal errors.
138
+
100
139
## The database schema of a LDAP identity
101
140
102
141
```sql
103
142
CREATE TABLE _auth_identity_ldap
104
143
(
105
144
id text PRIMARY KEY REFERENCES _auth_identity (id),
106
145
app_id text NOT NULL,
107
-
server_url text NOT NULL,
108
-
distinguished_name text NOT NULL,
146
+
server_name text NOT NULL,
147
+
user_id_attribute text NOT NULL,
148
+
user_id_value text NOT NULL,
109
149
claims jsonb NOT NULL,
110
150
raw_entry_json jsonb NOT NULL
111
151
);
112
152
113
-
CREATE UNIQUE INDEX _auth_identity_ldap_unique ON _auth_identity_ldap (app_id, server_url, distinguished_name);
153
+
CREATE UNIQUE INDEX _auth_identity_ldap_unique ON _auth_identity_ldap (app_id, server_name, user_id_attribute, user_id_value);
114
154
```
115
155
116
156
-`id`: The primary key of this table. This is the same as other `_auth_identity_*` tables.
117
157
-`app_id`: The app ID of this table for multi-tenant. This is the same as other `_auth_identity_*` tables.
118
-
- `server_url`: The URL to the LDAP server when this identity was created. The value is taken from the configuration at that moment. It does not change even if the URL in `authgear.yaml` changes.
119
-
- `distinguished_name`: The distinguished name of this LDAP entry.
158
+
-`server_name`: The `name` of the LDAP server.
159
+
-`user_id_attribute`: The `user_id_attribute` of the LDAP server when this identity is created.
160
+
-`user_id_value`: The value of the `user_id_attribute` of the user.
120
161
-`claims`: The standard claims extracted from this LDAP entry.
121
162
-`raw_entry_json`: The raw LDAP entry encoded in JSON. It looks like `{ "dn": "uid=johndoe,dc=example,dc=com", "attr1": ["value1"] }`.
122
163
123
164
## Handling of a LDAP identity
124
165
125
-
- To look up a LDAP identity in Authgear, we use the tuple `(app_id, server_url, distinguished_name)`.
166
+
- To look up a LDAP identity in Authgear, we use the tuple `(app_id, server_name, user_id_attribute, user_id_value)`.
126
167
- Similar to OAuth identity, we update an LDAP identity when it is used in login.
127
168
128
169
## The UX of LDAP in Auth UI
@@ -131,3 +172,12 @@ In the MVP phase (that is, now), sign in with LDAP is like sign in with an OAuth
131
172
Except that the enter-username-and-password page is hosted by Authgear as a integral part of Auth UI.
132
173
133
174
In the future, we may consider an option to make LDAP "replaces" Login ID in the UX.
175
+
176
+
## Errors
177
+
178
+
This section documents the expected errors.
179
+
180
+
|Description|Name|Reason|Info|
181
+
|---|---|---|---|
182
+
|When the LDAP server is service unavailable, `user_id_attribute` not found in a user, search filter turns out to be invalid, etc|InternalError|UnexpectedError||
183
+
|When the end-user cannot authenticate to the LDAP server|Unauthorized|InvalidCredentials||
0 commit comments