我将首先描述我的应用程序如何在没有LDAP的情况下工作。 我有使用WCF服务的WPF应用程序(身份验证 windows 或 UserName 取决于用户选择)。该服务允许与数据库通信。
我向用户显示"登录屏幕"为了让他能够设置她的用户名"和#34;密码"然后应用程序连接到服务并使用检查UserName和Password是否存在于数据库中的函数。 (见下面的img)
现在我还需要集成LDAP以根据现有系统验证用户帐户,而不必创建另一个登录帐户。
我对LDAP一无所知,对许多事情感到困惑。请原谅可能使用错误的术语。
我用谷歌搜索,但我仍然没有很多问题的答案。1-我的数据库表中存在的用户与#34; User"之间的关系是什么?和我应该在LDAP中创建的配置文件?
2-我应该做些什么来允许用户从LDAP访问我的应用程序并使用我服务的所有功能?
3-我应该有服务类型" LDAP"就像我今天在我的应用程序中使用的其他身份验证类型(" Windows"和" UserName")?
4-如果我想更新上图所示的应用程序架构,我应该在哪里添加LDAP?
答案 0 :(得分:4)
首先,我将逐一回答您的问题,
LDAP上的用户在数据库中是相同的,您可以在用户表中保存LDAP的用户名及其域名, 但LDAP上的配置文件可能因配置文件表而异,但可以从LDAP地址获取。
通过LDAP检查用户名和密码就足够了,只需要在表中保存LDAP地址(例如ExternalPath)并在User和ExternalPath表之间建立关系。 LDAP地址包含一些规范。
是的,您必须有一个单独的机制来识别LDAP用户,我将进一步解释。
如果一切都是原子的并且设计得恰到好处,这并不难,在进一步的步骤中你可能会觉得它很容易。
让我讲述我在LDAP和身份验证用户LDAP和DB以及我们的架构方面的经验。
我实现了一个名为Auth.svc
的WCF服务,此服务包含一个名为AuthenticateAndAuthorizeUser
的方法,这对于来自LDAP或任何地方的用户来说是透明的。
我希望您通过以下步骤获得通过LDAP和DB对用户进行身份验证的线索和体系结构:
1 - 首先我有一个名为Users
的表,其中包含用户信息,还有一个名为ExternalPath
的字段作为外键,如果为空则指定UserName在DB中知道它的密码,否则它来自UserDirectory
。
2 - 在第二步中,您必须保留LDAP地址(在我的情况下,LDAP地址在ExternalPath
表中),所有LDAP地址通常都在端口389
上。
3 - 实施身份验证用户,如果找不到(使用用户名和密码),请检查ExternalPath
以验证LDAP地址。
4 - 数据库架构应该类似于下面的屏幕截图。
如您所见,ExternalPath
字段指定用户是否来自LDAP。
5 - 在表示层我定义了LDAP服务器,如下面的截图
6 - 在另一方面,在系统中添加新用户时,您可以为我的用户定义LDAP我在添加用户表单时在DropDown中列出LDAP标题(如果管理员选择然后,LDAP地址不需要获取密码并将其保存在DB 中,因为我提到只需要保存LDAP用户名而不是密码。
7 - 但最后一件事是在LDAP和DB上验证用户。
因此,身份验证方法类似于:
User userLogin = User.Login<User>(username, password, ConnectionString, LogFile);
if (userLogin != null)
return InitiateToken(userLogin, sourceApp, sourceAddress, userIpAddress);
else//Check it's LDAP path
{
User user = new User(ConnectionString, LogFile).GetUser(username);
if (user != null && user.ExternalPath != null)
{
LDAPSpecification spec = new LDAPSpecification
{
UserName = username,
Password = password,
Path = user.ExternalPath.Path,
Domain = user.ExternalPath.Domain
};
bool isAthenticatedOnLDAP = LDAPAuthenticateUser(spec);
}
}
如果输入的用户名和密码在DB中不存在userLogin
,那么我们应该通过相关的LDAP地址对其进行身份验证。
在else
阻止中找到User from Users表,如果此字段不为null,则获取ExternalPath
表示用户在LDAP上。
8 - LDAPAuthenticateUser
方法是:
public bool LDAPAuthenticateUser(LDAPSpecification spec)
{
string pathDomain = string.Format("LDAP://{0}", spec.Path);
if (!string.IsNullOrEmpty(spec.Domain))
pathDomain += string.Format("/{0}", spec.Domain);
DirectoryEntry entry = new DirectoryEntry(pathDomain, spec.UserName, spec.Password, AuthenticationTypes.Secure);
try
{
//Bind to the native AdsObject to force authentication.
object obj = entry.NativeObject;
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + spec.UserName + ")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
if (null == result)
{
return false;
}
}
catch (Exception ex)
{
Logging.Log(LoggingMode.Error, "Error authenticating user on LDAP , PATH:{0} , UserName:{1}, EXP:{2}", pathDomain, spec.UserName, ex.ToString());
return false;
}
return true;
}
如果在LDAPAuthenticateUser
中引发异常,则表示用户目录中不存在用户。
身份验证代码接受域,用户名,密码以及Active Directory中树的路径。
上面的代码使用LDAP目录提供程序验证方法调用LDAPAuthenticateUser
并传入从用户收集的凭据。然后,使用目录树的路径,用户名和密码创建DirectoryEntry对象。 DirectoryEntry
对象尝试通过获取AdsObject
属性来强制NativeObject
绑定。如果成功,则通过创建CN
对象并过滤DirectorySearcher
来获取用户的SAMAccountName
属性。在用户进行身份验证并且异常未发生后,方法返回true表示用户在给定的LDAP地址上查找。
要查看有关轻量级目录访问协议的更多信息并对其进行身份验证,THIS Link可以提供更多有关规范的信息。
希望能帮助你。