C# 如何使用System.DirectoryServices.Protocol验证用户名/密码?
首先,我不能使用Active Directory,因此我不能直接使用C# 如何使用System.DirectoryServices.Protocol验证用户名/密码?,c#,directoryservices,novell,C#,Directoryservices,Novell,首先,我不能使用Active Directory,因此我不能直接使用System.DirectoryServices。这将是一台PC向Novell网络发送查询,该网络仅支持System.DirectoryServices.Protocol 我很确定我需要提供适当的搜索请求 这就是我到目前为止所做的: private static String _certificatePath; private static String _server; private static SearchRespon
System.DirectoryServices
。这将是一台PC向Novell网络发送查询,该网络仅支持System.DirectoryServices.Protocol
我很确定我需要提供适当的搜索请求
这就是我到目前为止所做的:
private static String _certificatePath;
private static String _server;
private static SearchResponse Query(String user, String pwd, out String error)
{
SearchResponse result = null;
error = String.Empty;
if (File.Exists(_certificatePath))
{
var identifier = new LdapDirectoryIdentifier(_server, false, false);
try
{
using (var connection = new LdapConnection(identifier))
{
connection.SessionOptions.ProtocolVersion = 3;
var cert = new X509Certificate();
cert.Import(_certificatePath, null, X509KeyStorageFlags.DefaultKeySet);
connection.ClientCertificates.Add(cert);
connection.AuthType = AuthType.External;
connection.AutoBind = false;
var request = new SearchRequest()
{
DistinguishedName = user, //Find this person
Filter = "(objectClass=*)", //The type of entry we are looking for
Scope = System.DirectoryServices.Protocols.SearchScope.Subtree, //We want all entries below this ou
};
result = (SearchResponse)connection.SendRequest(request); //Run the query and get results
}
} catch (Exception err)
{
error = String.Format("SDSP::Query {0}: {1}", err.GetType(), err.Message);
}
}
else
{
error = "The system cannot find the Cryptography Certificate at the path specified in the Application Configuration file.";
}
return result;
}
如何创建验证用户/pwd
组合的密码
var request = new SearchRequest()
{
DistinguishedName = user, //Find this person
Filter = "(objectClass=*)", //The type of entry we are looking for
Scope = System.DirectoryServices.Protocols.SearchScope.Subtree, //We want all entries below this ou
};
让我向您展示我为实现这一验证所做的最佳尝试,也许它会对您有用 在我的上下文中,这不起作用,因为我的管理员用户无法读取属性“userPassword”,我也不知道为什么。我猜是有一些权限没有分配 无论如何,这是代码,希望它有帮助:
var server = "<SERVER:PORT>";
var adminUser = "<USERNAME>";
var adminPass = "<PASSWORD>";
using (var ldap = new LdapConnection(server))
{
ldap.SessionOptions.ProtocolVersion = 3;
// To simplify this example I'm not validating certificate. Your code is fine.
ldap.SessionOptions.VerifyServerCertificate += (connection, certificate) => true;
ldap.SessionOptions.SecureSocketLayer = true;
ldap.AuthType = AuthType.Basic;
ldap.Bind(new System.Net.NetworkCredential($"cn={adminUser},o=<ORGANIZATION>", adminPass));
// Now I will search to find user's DN.
// If you know exact DN, then you don't need to search, go to compare request directly.
var search = new SearchRequest
{
//Here goes base DN node to start searching. Node closest to entry improves performance.
// Best base DN is one level above.
DistinguishedName = "<BASEDN>", //i.e.: ou=users,o=google
Filter = "uid=<USERNAME>",
Scope = SearchScope.OneLevel
};
// Adding null to attributes collection, makes attributes list empty in the response.
// This improves performance because we don't need any info of the entry.
search.Attributes.Add(null);
var results = (SearchResponse)ldap.SendRequest(search);
if (results.Entries.Count == 0)
throw new Exception("User not found");
// Because I'm searching "uid" can't exists more than one entry.
var entry = results.Entries[0];
// Here I use DN from entry found.
var compare = new CompareRequest(entry.DistinguishedName, new DirectoryAttribute("userPassword", "<PASSWORD>"));
var response = (CompareResponse)ldap.SendRequest(compare);
if (response.ResultCode != ResultCode.CompareTrue)
throw new Exception("User and/or Password incorrect.");
}
var-server=”“;
var adminUser=“”;
var adminPass=“”;
使用(var ldap=new LdapConnection(服务器))
{
ldap.SessionOptions.ProtocolVersion=3;
//为了简化这个示例,我不验证证书。您的代码很好。
ldap.SessionOptions.VerifyServerCertificate+=(连接,证书)=>true;
ldap.SessionOptions.SecureSocketLayer=true;
ldap.AuthType=AuthType.Basic;
Bind(新的System.Net.NetworkCredential($“cn={adminUser},o=,adminPass));
//现在我将搜索以查找用户的DN。
//若您知道确切的DN,那个么您不需要搜索,直接转到比较请求。
var search=新的SearchRequest
{
//下面是开始搜索的基本DN节点。最靠近条目的节点提高了性能。
//最佳基本DN为一级以上。
DifferentizedName=“”,//即:ou=users,o=google
Filter=“uid=”,
Scope=SearchScope.OneLevel
};
//将null添加到attributes集合,将使响应中的attributes列表为空。
//这提高了性能,因为我们不需要任何条目信息。
search.Attributes.Add(空);
var results=(SearchResponse)ldap.SendRequest(search);
if(results.Entries.Count==0)
抛出新异常(“未找到用户”);
//因为我正在搜索“uid”不能存在多个条目。
var条目=结果。条目[0];
//在这里,我使用从找到的条目中找到的DN。
var compare=new CompareRequest(entry.differentizedName,new DirectoryAttribute(“userPassword”),“”);
var response=(comparereresponse)ldap.SendRequest(compare);
if(response.ResultCode!=ResultCode.CompareTrue)
抛出新异常(“用户和/或密码不正确”);
}
在Windows上
您可以附加ContextOptions。协商ValidateCredentials
(用户名和密码)的参数
资料来源:
关于Novell
和都是高级类工具,是Active Directory的包装器
//use the users credentials for the query
DirectoryEntry root = new DirectoryEntry(
"LDAP://dc=domain,dc=com",
loginUser,
loginPassword
);
//query for the username provided
DirectorySearcher searcher = new DirectorySearcher(
root,
"(sAMAccountName=" + loginUser + ")"
);
//a success means the password was right
bool success = false;
try {
searcher.FindOne();
success = true;
}
catch {
success = false;
}
请参阅此处的。相同问题。“你知道怎么做吗?”小丑编码器-我没有,但谢谢你的提醒。“我现在可以为此发布悬赏了。@小丑程序员-试着找到一种安装证书的方法。它将来自Novell(如果您试图访问Novell服务器)。一旦该证书被加载(就像我在上面的示例中所做的那样),您就不需要使用“管理员”帐户登录。我这样做了,但它不起作用,但我怀疑我的情况与关闭的功能有关。看看我对AsifAli72090答案的评论……networkCredential对象似乎符合要求,除非我错了。今天有另一个答案发布了。听起来合乎逻辑:尝试使用提供的用户名和密码组合进行绑定。我暂时无法使用Novell系统。你能试试这段代码,让我知道它对你是否有效吗?@jp2code AsifAli72090发布的代码示例是最简单、最有效的方法。但您需要对每个用户授予绑定权限。如果你没有任何限制(就像我一样),那么这是最好的解决方案。如果您所处的环境不允许所有人都绑定,那么验证用户/密码的唯一方法就是通过“userPassword”属性比较密码。我第一次尝试解决这个问题,但它在我的环境中不起作用。这是我第一次尝试验证用户/密码,因为它不起作用,我开始使用CompareRequest。我最近发现,如果我在一个用户上打开通用密码,它将通过“bind”以及与“admin”用户的CompareRequest绑定开始验证。因此,我的结论是,如果不启用该功能,验证用户/密码对是不可能的。无论如何,我会继续尝试其他事情…@小丑编码器,是的,上的这个问题说,AuthType.Negotiate
是Windows特定的,所以它在Novell上不会被接受。你在这个Asif上提供了很多帮助。谢谢该死。和都是高级类工具,是Active Directory的包装器。它们不在名称空间中。我不能使用这个答案。以“On Novell”开头的部分不能在Novell上使用,因为它没有响应Active Directory调用的机制。也就是说,回到您的第一个代码段,我发现一个Apache服务器的帖子说,他们使用connection.AuthType=AuthType.Basic代码>与用户名和密码一起使用时。我还没有在我们客户的Novell系统上测试过这一点,但它看起来在逻辑上是合理的。
//use the users credentials for the query
DirectoryEntry root = new DirectoryEntry(
"LDAP://dc=domain,dc=com",
loginUser,
loginPassword
);
//query for the username provided
DirectorySearcher searcher = new DirectorySearcher(
root,
"(sAMAccountName=" + loginUser + ")"
);
//a success means the password was right
bool success = false;
try {
searcher.FindOne();
success = true;
}
catch {
success = false;
}