Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用System.DirectoryServices.Protocol验证用户名/密码?_C#_Directoryservices_Novell - Fatal编程技术网

C# 如何使用System.DirectoryServices.Protocol验证用户名/密码?

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

首先,我不能使用Active Directory,因此我不能直接使用
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;
}