简体   繁体   English

.net Web服务以使用SSL验证LDAP凭据

[英].net web service to validate LDAP credentials using SSL

So I'm new to the whole .net thing here, but basically what I want to do is write a web service that will take a SOAP request with user's name and password and check them against an ldap server to validate that the credentials are right. 因此,我对整个.net还是陌生的,但是基本上我想做的是编写一个Web服务,该服务将接收带有用户名和密码的SOAP请求,并在ldap服务器上检查它们以验证凭据是否正确。 I've already done this in perl, the code is below, but I'd like to replicate it in .net to get some more exposure to it. 我已经在perl中完成了此操作,代码在下面,但是我想在.net中复制它,以进一步了解它。 I've been poking around with c# since I've done a good amount of java programming and it seems like they are pretty similar, but if it's easier in vb or something else I'm not opposed to that. 我一直在使用c#,因为我已经做了大量的Java编程,而且看起来它们很相似,但是如果在vb或其他方面更容易,我不反对。

The main problem I'm having is actually connecting to the server itself. 我遇到的主要问题实际上是连接到服务器本身。 I've found some examples online but I'm getting confused as to what I should be passing to various methods. 我在网上找到了一些示例,但是对于应该传递给各种方法的内容我感到困惑。 Here is the perl version of the web service: 这是Web服务的perl版本:

authenticate.cgi authenticate.cgi

use strict;
use warnings;
use SOAP::Transport::HTTP;
SOAP::Transport::HTTP::CGI
    ->dispatch_to('Authenticate')
    ->handle;

package Authenticate;

use Net::LDAPS;
use Net::LDAP;

sub Verify{
    my ($class, $user, $pass) = @_;

    my $user_dn = "uid=$user,ou=people,o=domain";

    my $ldap = Net::LDAPS->new( 'ldap.domain.com', port => '636' ) or die "$@";

    my $mesg = $ldap->bind($user_dn, password => $pass);

    return $mesg->error if $mesg->is_error;

    return "Successful authentication for user '$user'";
}

What i've been messing with in c# is the following (I might have unnecessary includes, i've been messing with a bunch of things): 我一直在用C#弄乱的是以下内容(我可能有不必要的包含,我一直在弄乱一堆东西):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.DirectoryServices;
using System.DirectoryServices.Protocols;
using System.Net;


/// <summary>
/// Summary description for WebService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment     the following line. 
// [System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService {

    public WebService () {

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }

    [WebMethod]
    public string Authenticate(string username, string pwd) {
        string domain = "LDAP://ldap.domain.com:636";
        string domainAndUsername = domain + @"\" + username;
        string path = domain + @"/ou=people,o=domain";
        string filterAttribute;
        DirectoryEntry entry = new DirectoryEntry(path, domainAndUsername, pwd);

        try
        {
            //Bind to the native AdsObject to force authentication.
            object obj = entry.NativeObject;

            DirectorySearcher search = new DirectorySearcher(entry);

            search.Filter = "(SAMAccountName=" + username + ")";
            search.PropertiesToLoad.Add("cn");
            SearchResult result = search.FindOne();

            if (null == result)
            {
                return "false";
            }

            //Update the new path to the user in the directory.
            path = result.Path;
            filterAttribute = (string)result.Properties["cn"][0];
        }
        catch (Exception ex)
        {
            throw new Exception("Error authenticating user. " + ex.Message);
        }

        return "true";
    }

}

This has been resulting in the error 这导致了错误

System.Exception: Error authenticating user. System.Exception:验证用户时出错。 The server is not operational. 服务器无法运行。

I feel like I am just specifying the path wrong somewhere or something like that, but I can't seem to figure it out. 我觉得我只是在某处或类似的地方指定了错误的路径,但我似乎无法弄清楚。

It seems like this would create a path that looks like "LDAP://ldap.domain.com:636\\username/ou=people,o=domain" . 似乎这将创建一个看起来像"LDAP://ldap.domain.com:636\\username/ou=people,o=domain"的路径。 Typically it would be "LDAP://ldap.domain.com:636/cn=Full User Common Name,ou=People,dc=domain,dc=local" . 通常,它将是"LDAP://ldap.domain.com:636/cn=Full User Common Name,ou=People,dc=domain,dc=local"

If you don't have the DN to start off with, you should bind anonymously or with a service credential, search using SAMAccountName , then re-bind using the username and password. 如果没有DN,则应匿名绑定或使用服务凭证绑定,使用SAMAccountName搜索,然后使用用户名和密码重新绑定。 Here is a good example from ASP.net. 是来自ASP.net的一个很好的示例。 The example, however, expects the username to be in uid form, which you would want to change to SAMAccountName 但是,该示例希望用户名采用uid形式,您需要将其更改为SAMAccountName

Also, it looks like you are specifying a TLS port, but you have not specified AuthenticationTypes.SecureSocketsLayer , which could cause the error you are receiving. 同样,您似乎在指定TLS端口,但尚未指定AuthenticationTypes.SecureSocketsLayer ,这可能会导致收到错误。

Based on your code, you're passing the following into the DirectoryEntry constructor: 根据您的代码,将以下内容传递给DirectoryEntry构造函数:

Path: LDAP://ldap.domain.com:636/ou=people,o=domain 路径: LDAP://ldap.domain.com:636/ou=people,o=domain

Username: LDAP://ldap.domain.com:636\\username 用户名: LDAP://ldap.domain.com:636\\username

That username is not right. 该用户名不正确。 If was Active Directory, you would put ldap.domain.com\\username but it doesn't look like this is Active Directory. 如果是Active Directory, ldap.domain.com\\username但看起来不是Active Directory。 So you should give the user's distinguished name. 因此,您应提供用户的专有名称。 From your perl, it looks like it should be uid=username,ou=people,o=domain , but that looks weird to me. 从您的perl看来,它应该是uid=username,ou=people,o=domain ,但这对我来说很奇怪。 I always see it as cn=username,ou=people,o=domain . 我总是将其视为cn=username,ou=people,o=domain

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM