Working with DirectoryServices in ASP.NET Core

2020-05-20 08:38发布

问题:

I am upgrading my ASP.NET Core RC1 application to RC2. I have some references to System.DirectoryServices and System.DirectoryServices.AccountManagement in some *.cs files so that I can query LDAP. But I have no idea how to add references to it in RC2 in the Project.json file. Everything that I try just gives me more errors. Any help is appreciated.

{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0-rc2-3002702",
      "type": "default"
    },
    "Microsoft.AspNetCore.Diagnostics": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview1-final",
    "Microsoft.EntityFrameworkCore": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview1-final",
    "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Newtonsoft.Json": "8.0.3",
    "Microsoft.Extensions.Logging": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc2-final",
    "System.Linq": "4.0.1-beta-23516",
    "System.Linq.Queryable": "4.0.1-beta-23516"
  },

  "tools": {
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    },
    "Microsoft.Extensions.SecretManager.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    }
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "dnxcore50",
        "portable-net45+win8"
      ]
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
  }
}

回答1:

The new CoreCLR doesn't support this library, at the moment. There's an open GitHub issue about this, where you can find more information and discussion. (A workaround is presented there if you are only using AD for your authentication system.)

If you're only planning on running this app on a Windows server, you could target "net452" for the framework and add the framework assemblies underneath that.

"frameworks": {
  "net452": {
    "frameworkAssemblies": {
      "System.DirectoryServices": "4.0.0.0",
      "System.DirectoryServices.AccountManagement": "4.0.0.0"
    }
  }
},


回答2:

Just want to say that they just issued a pre-release of the Microsoft.Windows.Compatibility which contains the System.DirectoryServices components needed to work directory with active directory... its beta, but its finally out there.

  • Nuget-icrosoft.Windows.Compatibility/2.0.0-preview1-25914-04


回答3:

Adding to Bastyons answer above, you can install System.DirectoryServices.AccountManagement in a .NET Core app as a NuGet package (preview version) from https://www.nuget.org/packages/System.DirectoryServices.AccountManagement/4.5.0-preview1-25914-04. Once installed, you can create a simple call to authenticate an AD user as follows:

public static bool ValidateCredentials(string userName, string password)
{
    try 
    {
        using (var adContext = new PrincipalContext(ContextType.Domain, "YOUR_AD_DOMAIN"))
        {
            return adContext.ValidateCredentials(userName, password);
        }
    }
    catch(Exception ex) 
    {
        throw ex;
    }
}

Update: This package is now available as a final version from https://www.nuget.org/packages/System.DirectoryServices.AccountManagement/4.5.0



回答4:

If you only want to authenticate users in .NET Core 2.0, you only need to add System.DirectoryServices Nuget package (no need to add Microsoft.Windows.Compatibility nuget package). It is also supported in .NET Standard 2.0

Note: I've only used below code in .NET Core 2.2, but the nuget compatibility info indicates that it works in .NET Core 2.0.

To validate password use:

var domainAndUsername = domain + @"\" + username;
var entry = new DirectoryEntry(_path, domainAndUsername, pwd);

object isValidPassword = null;
try
{
     // authenticate (check password)
     isValidPassword = entry.NativeObject;
}
catch (Exception ex)
{
      _logger.Log.Debug($"LDAP Authentication Failed for {domainAndUsername}"); 
      return false;
}

Furthermore, if you want to search for user in directory, below should work:

var search = new DirectorySearcher(entry) { Filter = "(SAMAccountName=" + username + ")" };
search.PropertiesToLoad.Add("cn");

var result = search.FindOne();

According to Github Issue, System.DirectoryServices.AccountManagement isn't yet supported for LDAP. Beyond that, previous info provided by @zdub and @Bastyon still seems valid.



回答5:

You can use LDAP client library for .NET Standard 1.3
Compatible .NET runtimes: .NET Core, .NET Framework 4.6, ...
It works against any LDAP protocol compatible directory server (including Microsoft Active Directory).

private static bool LoginLdap(string username, string password)
{
    try
    {
        using (var conn = new LdapConnection())
        {
            conn.Connect("<LdapHost>", 389);
            conn.Bind(LdapConnection.Ldap_V3, $"<yourDomain>\\{username}", password);
        }
        return true;
    }
    catch (LdapException)
    {
        return false;
    }            
}

For more info read this issue : Support for System.DirectoryServices
It works well for me. (in .NET Core 1.1.1)