mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
Add ability to search for groups using {uid}
On some LDAP servers, the `uid` attribute is more like a guid, while the username exists instead in a dedicated field, like `username`. This means the `uid` is not necessarily equal to `username`. This is allows referencing using the `uid` to search for groups in the same way as `dn` so that one can explicitly match the `memberuid` to the `uid` for the user without the assumptions that come with using `{0}`.
This commit is contained in:
parent
23e28ee659
commit
264a94d4e7
|
@ -61,6 +61,7 @@ authentication_backend:
|
|||
# The groups filter used for retrieving groups of a given user.
|
||||
# {0} is a matcher replaced by username.
|
||||
# {dn} is a matcher replaced by user DN.
|
||||
# {uid} is a matcher replaced by user uid.
|
||||
# 'member={dn}' by default.
|
||||
groups_filter: (&(member={dn})(objectclass=groupOfNames))
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ authentication_backend:
|
|||
# The groups filter used for retrieving groups of a given user.
|
||||
# {0} is a matcher replaced by username.
|
||||
# {dn} is a matcher replaced by user DN.
|
||||
# {uid} is a matcher replaced by user uid.
|
||||
# 'member={dn}' by default.
|
||||
groups_filter: (&(member={dn})(objectclass=groupOfNames))
|
||||
|
||||
|
|
|
@ -83,6 +83,49 @@ describe("ldap/Session", function () {
|
|||
});
|
||||
});
|
||||
|
||||
it("should replace {uid} by user uid when searching for groups in LDAP", function () {
|
||||
const USER_UID = "user1";
|
||||
const options: LdapConfiguration = {
|
||||
url: "ldap://ldap",
|
||||
additional_users_dn: "ou=users",
|
||||
additional_groups_dn: "ou=groups",
|
||||
base_dn: "dc=example,dc=com",
|
||||
users_filter: "cn={0}",
|
||||
groups_filter: "member=cn={uid},ou=users,dc=example,dc=com",
|
||||
group_name_attribute: "cn",
|
||||
mail_attribute: "mail",
|
||||
user: "cn=admin,dc=example,dc=com",
|
||||
password: "password"
|
||||
};
|
||||
const ldapClient = new ConnectorStub();
|
||||
|
||||
// Retrieve user DN
|
||||
ldapClient.searchAsyncStub.withArgs("ou=users,dc=example,dc=com", {
|
||||
scope: "sub",
|
||||
sizeLimit: 1,
|
||||
attributes: ["uid"],
|
||||
filter: "cn=user1"
|
||||
}).returns(BluebirdPromise.resolve([{
|
||||
uid: USER_UID
|
||||
}]));
|
||||
|
||||
// Retrieve groups
|
||||
ldapClient.searchAsyncStub.withArgs("ou=groups,dc=example,dc=com", {
|
||||
scope: "sub",
|
||||
attributes: ["cn"],
|
||||
filter: "member=cn=user1,ou=users,dc=example,dc=com"
|
||||
}).returns(BluebirdPromise.resolve([{
|
||||
cn: "group1"
|
||||
}]));
|
||||
|
||||
const client = new Session(ADMIN_USER_DN, ADMIN_PASSWORD, options, ldapClient, Winston);
|
||||
|
||||
return client.searchGroups("user1")
|
||||
.then(function (groups: string[]) {
|
||||
Assert.deepEqual(groups, ["group1"]);
|
||||
});
|
||||
});
|
||||
|
||||
it("should retrieve mail from custom attribute", function () {
|
||||
const USER_DN = "cn=user1,ou=users,dc=example,dc=com";
|
||||
const options: LdapConfiguration = {
|
||||
|
|
|
@ -61,6 +61,12 @@ export class Session implements ISession {
|
|||
return BluebirdPromise.resolve(userGroupsFilter.replace("{dn}", userDN));
|
||||
});
|
||||
}
|
||||
else if (userGroupsFilter.indexOf("{uid}") > 0) {
|
||||
return this.searchUserUid(username)
|
||||
.then(function (userUid: string) {
|
||||
return BluebirdPromise.resolve(userGroupsFilter.replace("{uid}", userUid));
|
||||
});
|
||||
}
|
||||
return BluebirdPromise.resolve(userGroupsFilter);
|
||||
}
|
||||
|
||||
|
@ -83,29 +89,37 @@ export class Session implements ISession {
|
|||
});
|
||||
}
|
||||
|
||||
searchUserDn(username: string): BluebirdPromise<string> {
|
||||
searchUserAttribute(username: string, attribute: string): BluebirdPromise<string> {
|
||||
const that = this;
|
||||
const filter = this.options.users_filter.replace("{0}", username);
|
||||
this.logger.debug("Computed users filter is %s", filter);
|
||||
const query = {
|
||||
scope: "sub",
|
||||
sizeLimit: 1,
|
||||
attributes: ["dn"],
|
||||
attributes: [attribute],
|
||||
filter: filter
|
||||
};
|
||||
|
||||
that.logger.debug("LDAP: searching for user dn of %s", username);
|
||||
that.logger.debug("LDAP: searching for user %s of %s", attribute, username);
|
||||
return that.connector.searchAsync(this.usersSearchBase, query)
|
||||
.then(function (users: { dn: string }[]) {
|
||||
.then(function (users: { [attribute: string]: string }[]) {
|
||||
if (users.length > 0) {
|
||||
that.logger.debug("LDAP: retrieved user dn is %s", users[0].dn);
|
||||
return BluebirdPromise.resolve(users[0].dn);
|
||||
that.logger.debug("LDAP: retrieved user %s is %s", attribute, users[0][attribute]);
|
||||
return BluebirdPromise.resolve(users[0][attribute]);
|
||||
}
|
||||
return BluebirdPromise.reject(new Error(
|
||||
Util.format("No user DN found for user '%s'", username)));
|
||||
Util.format("No user %s found for user '%s'", attribute, username)));
|
||||
});
|
||||
}
|
||||
|
||||
searchUserDn(username: string): BluebirdPromise<string> {
|
||||
return this.searchUserAttribute(username, "dn");
|
||||
}
|
||||
|
||||
searchUserUid(username: string): BluebirdPromise<string> {
|
||||
return this.searchUserAttribute(username, "uid");
|
||||
}
|
||||
|
||||
searchEmails(username: string): BluebirdPromise<string[]> {
|
||||
const that = this;
|
||||
const query = {
|
||||
|
|
Loading…
Reference in New Issue
Block a user