Basf_FCL/FCL/FineUIPro.Web/common/LdapAuthentication.cs

614 lines
22 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.DirectoryServices;
using System.DirectoryServices.Protocols;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace FineUIPro.Web
{
public sealed class LdapAuthentication
{
private bool _allowAnyCertificates;
private string _domain;
private string _path;
private string _userNameProxyUser;
private string _passwordProxyUser;
private AuthenticationTypes _authenticationType;
public static readonly string LdapUriString = "LDAP";
public static readonly int LdapPort = 389;
public static readonly int LdapPortSsl = 636;
private X509Certificate _locallyVerificationCertificate;
private string _locallyVerificationCertificateSerialNumber;
private bool _useSecureSocketLayer;
private bool _verifyCertificateLocally;
private LdapDirectoryIdentifier _directoryIdentifier;
public bool AllowAnyCertificates
{
get
{
return _allowAnyCertificates;
}
set
{
_allowAnyCertificates = value;
}
}
public string Domain
{
get
{
return _domain;
}
set
{
_domain = value;
}
}
public string Path
{
get
{
return _path;
}
set
{
_path = value;
}
}
public string UserNameProxyUser
{
get
{
return _userNameProxyUser;
}
set
{
_userNameProxyUser = value;
}
}
public string PasswordProxyUser
{
get
{
return _passwordProxyUser;
}
set
{
_passwordProxyUser = value;
}
}
public AuthenticationTypes AuthenticationType
{
get
{
return _authenticationType;
}
set
{
_authenticationType = value;
}
}
public X509Certificate LocallyVerificationCertificate
{
get
{
return _locallyVerificationCertificate;
}
set
{
_locallyVerificationCertificate = value;
}
}
public string LocallyVerificationCertificateSerialNumber
{
get
{
return _locallyVerificationCertificateSerialNumber;
}
set
{
_locallyVerificationCertificateSerialNumber = value;
}
}
public bool UseSecureSocketLayer
{
get
{
return _useSecureSocketLayer;
}
set
{
lock (this)
{
_useSecureSocketLayer = value;
}
}
}
public bool VerifyCertificateLocally
{
get
{
return _verifyCertificateLocally;
}
set
{
lock (this)
{
_verifyCertificateLocally = value;
}
}
}
public LdapDirectoryIdentifier DirectoryIdentifier
{
get
{
if (_directoryIdentifier == null)
{
lock (this)
{
SetDirectoryIdentifier();
}
}
return _directoryIdentifier;
}
}
public LdapAuthentication()
{
_authenticationType = AuthenticationTypes.FastBind;
}
private void SetDirectoryIdentifier()
{
int num = 0;
_directoryIdentifier = new LdapDirectoryIdentifier(portNumber: (!UseSecureSocketLayer) ? LdapPort : LdapPortSsl, server: _domain);
}
public DirectoryEntry GetDirectoryEntryOfProxyUser()
{
string text = $"{LdapUriString}://{_domain}/{_path}";
using (DirectoryEntry result = new DirectoryEntry(text, _userNameProxyUser, _passwordProxyUser, _authenticationType))
{
try
{
return result;
}
catch (Exception innerException)
{
throw new Exception(text, innerException);
}
}
}
private bool OnLdapConnectionVerifyServerCertificate(LdapConnection connection, X509Certificate serverCertificate)
{
if (AllowAnyCertificates)
{
return true;
}
if (!VerifyCertificateLocally)
{
return true;
}
if (LocallyVerificationCertificate != null)
{
if (LocallyVerificationCertificate.Equals(serverCertificate))
{
return true;
}
return false;
}
if (!string.IsNullOrEmpty(LocallyVerificationCertificateSerialNumber))
{
if (serverCertificate.GetSerialNumberString() == LocallyVerificationCertificateSerialNumber)
{
return true;
}
return false;
}
X509Store x509Store = new X509Store("My");
x509Store.Open(OpenFlags.ReadOnly);
X509Certificate2Enumerator enumerator = x509Store.Certificates.GetEnumerator();
while (enumerator.MoveNext())
{
X509Certificate2 current = enumerator.Current;
if (current.SerialNumber == serverCertificate.GetSerialNumberString())
{
return true;
}
}
return false;
}
public bool CheckPassword(string userName, string password)
{
Collection<string> groupMemberships = null;
LdapUser ldapUserInfo = null;
return CheckPassword(userName, password, readGroupMemberships: false, out groupMemberships, readLdapUserInfo: false, out ldapUserInfo);
}
public bool CheckPassword(string userName, string password, out Collection<string> groupMemberships)
{
LdapUser ldapUserInfo = null;
return CheckPassword(userName, password, readGroupMemberships: true, out groupMemberships, readLdapUserInfo: false, out ldapUserInfo);
}
public bool CheckPassword(string userName, string password, out LdapUser ldapUserInfo)
{
Collection<string> groupMemberships = null;
return CheckPassword(userName, password, readGroupMemberships: false, out groupMemberships, readLdapUserInfo: true, out ldapUserInfo);
}
public bool CheckPassword(string userName, string password, out Collection<string> groupMemberships, out LdapUser ldapUserInfo)
{
return CheckPassword(userName, password, readGroupMemberships: true, out groupMemberships, readLdapUserInfo: true, out ldapUserInfo);
}
private bool CheckPassword(string userName, string password, bool readGroupMemberships, out Collection<string> groupMemberships, bool readLdapUserInfo, out LdapUser ldapUserInfo)
{
if (string.IsNullOrEmpty(userName))
{
throw new ArgumentNullException("userName");
}
if (string.IsNullOrEmpty(password))
{
throw new ArgumentNullException("password");
}
if (password.Length >= 128)
{
throw new Exception();
}
groupMemberships = null;
ldapUserInfo = null;
List<string> list = new List<string>();
DirectoryEntry directoryEntryOfProxyUser = GetDirectoryEntryOfProxyUser();
if (directoryEntryOfProxyUser == null)
{
throw new Exception();
}
lock (this)
{
using (LdapConnection ldapConnection = new LdapConnection(DirectoryIdentifier))
{
try
{
ldapConnection.SessionOptions.SecureSocketLayer = UseSecureSocketLayer;
if (UseSecureSocketLayer && (AllowAnyCertificates || VerifyCertificateLocally))
{
LdapSessionOptions sessionOptions = ldapConnection.SessionOptions;
sessionOptions.VerifyServerCertificate = (VerifyServerCertificateCallback)Delegate.Combine(sessionOptions.VerifyServerCertificate, new VerifyServerCertificateCallback(OnLdapConnectionVerifyServerCertificate));
}
ldapConnection.Credential = new NetworkCredential(UserNameProxyUser, PasswordProxyUser);
ldapConnection.AuthType = AuthType.Basic;
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.Bind();
}
catch (DirectoryServicesCOMException innerException)
{
throw new Exception("Proxyuser_NotFound", innerException);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (UseSecureSocketLayer && (AllowAnyCertificates || VerifyCertificateLocally))
{
LdapSessionOptions sessionOptions2 = ldapConnection.SessionOptions;
sessionOptions2.VerifyServerCertificate = (VerifyServerCertificateCallback)Delegate.Remove(sessionOptions2.VerifyServerCertificate, new VerifyServerCertificateCallback(OnLdapConnectionVerifyServerCertificate));
}
}
string ldapFilter = $" (cn={userName})";
if (readGroupMemberships)
{
list.Add("groupmembership");
}
if (readLdapUserInfo)
{
GetUserAttrs(list);
}
SearchRequest request = new SearchRequest(_path, ldapFilter, System.DirectoryServices.Protocols.SearchScope.Subtree, list.ToArray());
SearchResponse searchResponse = (SearchResponse)ldapConnection.SendRequest(request);
if (searchResponse == null || searchResponse.Entries == null || searchResponse.Entries.Count < 1)
{
throw new Exception();
}
SearchResultEntry searchResultEntry = searchResponse.Entries[0];
string distinguishedName = searchResultEntry.DistinguishedName;
if (readGroupMemberships)
{
groupMemberships = ReadGroupMembershipsInternal(searchResultEntry);
}
if (readLdapUserInfo)
{
ldapUserInfo = GetUserInfoFromDirectoryEntry(searchResultEntry);
}
ldapConnection.Credential = new NetworkCredential(distinguishedName, password);
try
{
ldapConnection.Bind();
}
catch (LdapException innerException2)
{
throw new Exception("LdapAuthentication_WrongPassword", innerException2);
}
return true;
}
}
}
private static void GetUserAttrs(List<string> attrs)
{
attrs.Add("basfANRED");
attrs.Add("basfBuilding");
attrs.Add("basfCCCompany");
attrs.Add("basfCCPN");
attrs.Add("basfCompanyID");
attrs.Add("basfContractStatus");
attrs.Add("basfCostCenter");
attrs.Add("basfEPSapGroup");
attrs.Add("basfEPSapUserID");
attrs.Add("basfCCPN");
attrs.Add("basfGCDID");
attrs.Add("basfIDtype");
attrs.Add("basfPersg");
attrs.Add("basfPersonID");
attrs.Add("basfRegion");
attrs.Add("basfRPID");
attrs.Add("basfSBNR");
attrs.Add("basfSex");
attrs.Add("basfSIAMID");
attrs.Add("dn");
attrs.Add("cn");
attrs.Add("uid");
attrs.Add("co");
attrs.Add("employeeStatus");
attrs.Add("facsimileTelephoneNumber");
attrs.Add("fullName");
attrs.Add("givenName");
attrs.Add("GroupMembership");
attrs.Add("InternetEmailAddress");
attrs.Add("l");
attrs.Add("mobile");
attrs.Add("o");
attrs.Add("ou");
attrs.Add("postalCode");
attrs.Add("roomNumber");
attrs.Add("s");
attrs.Add("sa");
attrs.Add("surname");
attrs.Add("telephoneNumber");
attrs.Add("title");
attrs.Add("mail");
attrs.Add("sn");
attrs.Add("employeeNumber");
attrs.Add("basfUDMSID");
attrs.Add("postalAddress");
attrs.Add("c");
}
private static LdapUser GetUserInfoFromDirectoryEntry(SearchResultEntry entry)
{
LdapUser ldapUser = new LdapUser();
if (entry.Attributes.Contains("cn"))
{
ldapUser.UserName = (string)entry.Attributes["cn"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("mail"))
{
ldapUser.EmailAddress = (string)entry.Attributes["mail"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("givenName"))
{
ldapUser.FirstName = (string)entry.Attributes["givenName"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("sn"))
{
ldapUser.LastName = (string)entry.Attributes["sn"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("fullName"))
{
ldapUser.FullName = (string)entry.Attributes["fullName"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("o"))
{
ldapUser.Company = (string)entry.Attributes["o"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("ou"))
{
ldapUser.OrgCode = (string)entry.Attributes["ou"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("telephoneNumber"))
{
ldapUser.Phone = (string)entry.Attributes["telephoneNumber"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("basfGCDID"))
{
ldapUser.GcdId = (string)entry.Attributes["basfGCDID"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("basfPersonID"))
{
ldapUser.PersonId = (string)entry.Attributes["basfPersonID"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("employeeNumber"))
{
ldapUser.PersonalNr = (string)entry.Attributes["employeeNumber"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("basfCCPN"))
{
ldapUser.Ccpn = (string)entry.Attributes["basfCCPN"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("basfUDMSID"))
{
ldapUser.UdmsId = (string)entry.Attributes["basfUDMSID"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("postalAddress"))
{
ldapUser.Street = (string)entry.Attributes["postalAddress"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("l"))
{
ldapUser.City = (string)entry.Attributes["l"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("postalCode"))
{
ldapUser.ZipCode = (string)entry.Attributes["postalCode"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("c"))
{
ldapUser.Country = (string)entry.Attributes["c"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("facsimileTelephoneNumber"))
{
ldapUser.Fax = (string)entry.Attributes["facsimileTelephoneNumber"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("mobile"))
{
ldapUser.MobilePhone = (string)entry.Attributes["mobile"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("basfcompanyid"))
{
ldapUser.CompanyId = (string)entry.Attributes["basfcompanyid"].GetValues(typeof(string))[0];
}
if (entry.Attributes.Contains("basfidtype"))
{
ldapUser.BasfIdType = (string)entry.Attributes["basfidtype"].GetValues(typeof(string))[0];
}
return ldapUser;
}
private static Collection<string> ReadGroupMembershipsInternal(SearchResultEntry entry)
{
Collection<string> collection = new Collection<string>();
object[] values = entry.Attributes["groupmembership"].GetValues(typeof(string));
for (int i = 0; i < values.Length; i++)
{
string item = (string)values[i];
collection.Add(item);
}
return collection;
}
private static LdapUser GetUserInfoFromSearchResult(DirectoryEntry entry)
{
LdapUser ldapUser = new LdapUser();
if (entry.Properties.Contains("cn"))
{
ldapUser.UserName = entry.Properties["cn"].Value.ToString();
}
if (entry.Properties.Contains("mail"))
{
ldapUser.EmailAddress = entry.Properties["mail"].Value.ToString();
}
if (entry.Properties.Contains("givenName"))
{
ldapUser.FirstName = entry.Properties["givenName"].Value.ToString();
}
if (entry.Properties.Contains("sn"))
{
ldapUser.LastName = entry.Properties["sn"].Value.ToString();
}
if (entry.Properties.Contains("fullName"))
{
ldapUser.FullName = entry.Properties["fullName"].Value.ToString();
}
if (entry.Properties.Contains("o"))
{
ldapUser.Company = entry.Properties["o"].Value.ToString();
}
if (entry.Properties.Contains("ou"))
{
ldapUser.OrgCode = entry.Properties["ou"].Value.ToString();
}
if (entry.Properties.Contains("telephoneNumber"))
{
ldapUser.Phone = entry.Properties["telephoneNumber"].Value.ToString();
}
if (entry.Properties.Contains("basfGCDID"))
{
ldapUser.GcdId = entry.Properties["basfGCDID"].Value.ToString();
}
if (entry.Properties.Contains("basfPersonID"))
{
ldapUser.PersonId = entry.Properties["basfPersonID"].Value.ToString();
}
if (entry.Properties.Contains("employeeNumber"))
{
ldapUser.PersonalNr = entry.Properties["employeeNumber"].Value.ToString();
}
if (entry.Properties.Contains("basfCCPN"))
{
ldapUser.Ccpn = entry.Properties["basfCCPN"].Value.ToString();
}
if (entry.Properties.Contains("basfUDMSID"))
{
ldapUser.UdmsId = entry.Properties["basfUDMSID"].Value.ToString();
}
if (entry.Properties.Contains("postalAddress"))
{
ldapUser.Street = entry.Properties["postalAddress"].Value.ToString();
}
if (entry.Properties.Contains("l"))
{
ldapUser.City = entry.Properties["l"].Value.ToString();
}
if (entry.Properties.Contains("postalCode"))
{
ldapUser.ZipCode = entry.Properties["postalCode"].Value.ToString();
}
if (entry.Properties.Contains("c"))
{
ldapUser.Country = entry.Properties["c"].Value.ToString();
}
if (entry.Properties.Contains("facsimileTelephoneNumber"))
{
ldapUser.Fax = entry.Properties["facsimileTelephoneNumber"].Value.ToString();
}
if (entry.Properties.Contains("mobile"))
{
ldapUser.MobilePhone = entry.Properties["mobile"].Value.ToString();
}
if (entry.Properties.Contains("basfcompanyid"))
{
ldapUser.CompanyId = entry.Properties["basfcompanyid"].Value.ToString();
}
if (entry.Properties.Contains("basfidtype"))
{
ldapUser.BasfIdType = entry.Properties["basfidtype"].Value.ToString();
}
return ldapUser;
}
}
}