125 lines
3.7 KiB
C#
125 lines
3.7 KiB
C#
using System.Collections;
|
|
using System.ComponentModel;
|
|
using song_of_the_day;
|
|
using System.DirectoryServices.Protocols;
|
|
using System.Linq;
|
|
|
|
public class LdapIntegration
|
|
{
|
|
public static LdapIntegration? Instance;
|
|
|
|
private readonly string[] attributesToQuery = new string[]
|
|
{
|
|
"uid",
|
|
"givenName",
|
|
"sn",
|
|
"mail"
|
|
};
|
|
|
|
public LdapIntegration(string uri, int port, string adminBind, string adminPass)
|
|
{
|
|
this.Uri = uri;
|
|
this.Port = port;
|
|
this.AdminBind = adminBind;
|
|
this.AdminPass = adminPass;
|
|
}
|
|
|
|
private string Uri { get; set; }
|
|
|
|
private int Port { get; set; }
|
|
|
|
private string AdminBind { get; set; }
|
|
|
|
private string AdminPass { get; set; }
|
|
|
|
public bool TestLogin(string username, string password)
|
|
{
|
|
try
|
|
{
|
|
var userList = this.SearchInADAsUser(
|
|
AppConfiguration.Instance.LDAPConfig.LDAPQueryBase,
|
|
$"(uid={username})",
|
|
SearchScope.Subtree,
|
|
username,
|
|
password);
|
|
}
|
|
catch (LdapException ex)
|
|
{
|
|
if (ex.Message.Contains("credential is invalid"))
|
|
{
|
|
return false;
|
|
}
|
|
throw;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public List<LdapUser> SearchInAD(
|
|
string targetOU,
|
|
string query,
|
|
SearchScope scope
|
|
)
|
|
{
|
|
// search as admin
|
|
return this.SearchInADAsUser(targetOU, query, scope, this.AdminBind, this.AdminPass);
|
|
}
|
|
|
|
public List<LdapUser> SearchInADAsUser(
|
|
string targetOU,
|
|
string query,
|
|
SearchScope scope,
|
|
string userName,
|
|
string userPass
|
|
)
|
|
{
|
|
// on Windows the authentication type is Negotiate, so there is no need to prepend
|
|
// AD user login with domain. On other platforms at the moment only
|
|
// Basic authentication is supported
|
|
var authType = AuthType.Basic;
|
|
|
|
var user = userName.StartsWith("cn=") || userName.StartsWith("uid=") ? userName : "uid=" + userName + "," + AppConfiguration.Instance.LDAPConfig.LDAPUserQueryBase;
|
|
|
|
//var connection = new LdapConnection(ldapServer)
|
|
var connection = new LdapConnection(
|
|
new LdapDirectoryIdentifier(this.Uri, this.Port)
|
|
)
|
|
{
|
|
AuthType = authType,
|
|
Credential = new(user, userPass)
|
|
};
|
|
|
|
// the default one is v2 (at least in that version), and it is unknown if v3
|
|
// is actually needed, but at least Synology LDAP works only with v3,
|
|
// and since our Exchange doesn't complain, let it be v3
|
|
connection.SessionOptions.ProtocolVersion = 3;
|
|
|
|
// this is for connecting via LDAPS (636 port). It should be working,
|
|
// according to https://github.com/dotnet/runtime/issues/43890,
|
|
// but it doesn't (at least with Synology DSM LDAP), although perhaps
|
|
// for a different reason
|
|
//connection.SessionOptions.SecureSocketLayer = true;
|
|
|
|
connection.Bind();
|
|
|
|
var request = new SearchRequest(targetOU, query, scope, attributesToQuery);
|
|
|
|
var response = (System.DirectoryServices.Protocols.SearchResponse)connection.SendRequest(request);
|
|
|
|
var userList = new List<LdapUser>();
|
|
|
|
foreach (SearchResultEntry result in response.Entries)
|
|
{
|
|
userList.Add(new LdapUser()
|
|
{
|
|
UserId = result.Attributes["uid"][0].ToString(),
|
|
FirstName = result.Attributes["givenName"][0].ToString(),
|
|
LastName = result.Attributes["sn"][0].ToString(),
|
|
Email = result.Attributes["mail"][0].ToString(),
|
|
});
|
|
}
|
|
|
|
connection.Dispose();
|
|
|
|
return userList;
|
|
}
|
|
} |