New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for System.DirectoryServices for Windows #2089

Closed
syeshchenko opened this Issue Jun 18, 2015 · 188 comments

Comments

Projects
None yet
@syeshchenko

syeshchenko commented Jun 18, 2015

Execution plan:

  • 1. @ianhays to kick start the project in CoreFX repo - add source code, showing examples how to do it, advise with setting up build, packaging, prepare the project for future Linux/Mac ports, etc.).
  • 2. Make the code build on Windows.
    • CC @tquerec @ianhays @karelz on PRs
    • Note: We will not take any functional changes to the implementation, architecture, or API surface at this point unless they are necessary to make the code compile on .NET Core. Please give heads up on this issue as soon as you discover case like that.
    • 2.1. System.DirectoryServices.Protocol (on top of wldpap32.dll)
    • 2.2. System.DirectoryServices (on top of adsi.dll)
    • 2.3. System.DirectoryServices.AccountManagement (on top of System.DirectoryServices and SystemDirectoryServices.Protocols)
    • 2.4. System.DirectoryServices.ActiveDirectory (on top of Win32 APIs - see #2089 (comment))
  • 3. Add tests - progress tracked in #20669
  • .4. Linux/Mac ports.
    • 4.1. System.DirectoryServices.Protocol (we need to decide on x-plat LDAP library to use first) - tracked in #24843
    • 4.2. Other libraries (will be difficult as most implementation is mostly part of Windows) - to be tracked by separate issue(s) when the need arises
  • .5. Further improvements and bug fixes to DirectoryServices - to be tracked by separate issues (feel free to create them)
    • Potentially parallel with [4]
  • 6. Publish DirectoryServices package
    • 6.1. Publish preview DirectoryServices package - tracked in #18090
    • 6.2. Publish final DirectoryServices package - tracked as part of #24909

If anyone is working on any step, please mention it & coordinate here to avoid duplicated effort. @karelz will co-assign the issue to you as well.


Original proposal

Hello there, I was wondering if there is a chance to add support for System.DirectoryServices in CoreCLR.

In one of our projects we are trying to implement GAL based authentication on Linux and tried to use Mono for this task, however it only works partially, check for IsUserInGroup fails. This is something similar to what we are trying to get working: http://stackoverflow.com/questions/2188954/see-if-user-is-part-of-active-directory-group-in-c-sharp-asp-net

So I was hoping that with the addition of this namespace to CoreCLR, it might solve our problem!

Thank you

@joshfree joshfree added this to the Future milestone Oct 9, 2015

@danroth27

This comment has been minimized.

Member

danroth27 commented Oct 9, 2015

@joshfree joshfree assigned danroth27 and unassigned terrajobst Oct 12, 2015

@NickCraver

This comment has been minimized.

Member

NickCraver commented Jan 13, 2016

Is there any update on this?

@Eaglef90

This comment has been minimized.

Eaglef90 commented Jan 19, 2016

I too would like an update on this. My company is having me build a new app that requires the ability to query Active Directory via LDAP but it appears this is currently not possible. Is there planed support for it, is it being dropped in favor of something else, or is it already working just not documented anywhere?

@jozefizso

This comment has been minimized.

jozefizso commented Jan 20, 2016

A new, fresh look at implementing the LDAP and Active Directory support would be great to have in .NET CoreFX.

@coe-jeubanks

This comment has been minimized.

coe-jeubanks commented Jan 21, 2016

We really need an Active Directory/LDAP solution we can leverage in .NET Core. Whether it's a clean sheet implementation or a port of System.DirectoryServices doesn't matter as much to me. There are a lot of business-focused Windows applications that absolutely need AD auth, and LDAP auth would be a great feature bullet point for cross-platform developers.

@NickCraver

This comment has been minimized.

Member

NickCraver commented Jan 21, 2016

Agreed on the backwards compatible notes above - I don't feel a direct port is needed really, we just need a way to access auth (and perform other actions: search, unlock, delete, etc.) against Active Directory or any LDAP provider.

@terrajobst

This comment has been minimized.

Member

terrajobst commented Jan 22, 2016

@NickCraver

I don't feel a direct port is needed really, we just need a way to access auth [...] against Active Directory

That's good to know. Don't read too much into my port-to-core label I just applied. It's just my way of tracking gaps in the .NET Core offering that prevents customers like you from porting their app to .NET Core.

@NickCraver

This comment has been minimized.

Member

NickCraver commented Jan 22, 2016

@terrajobst Gotcha. I don't necessarily think this has to be a 1.0 item because of its modularity (and it sounds like it's slated for post-RTM anyway), but I do look forward to it. It'll be a blocker on porting Opserver for me, so happy to participate in API discussions if we can be of use. We have a wide range of use cases on the sysadmin side of things that may be helpful, ping if I can help out.

@sqmgh

This comment has been minimized.

sqmgh commented Jan 22, 2016

Just to throw another hat into the ring. At the moment this is the biggest blocker left for me as well. Simply being able to auth would be a huge help for now.

@Eaglef90

This comment has been minimized.

Eaglef90 commented Jan 29, 2016

Can we get an official response from someone on the dev team on the plans for this, if there are even any plans at all to support this?

@ghost

This comment has been minimized.

ghost commented Jan 31, 2016

I don't feel a direct port is needed really

Why? Sorry I am confused. Wouldn't that be the most easiest solution for everyone and in accord with DRY principle?
Nevertheless, if there is a reason to write the entire API from scratch, some consistency with old API (same method signatures) would be less confusing for consumer.

@NickCraver

This comment has been minimized.

Member

NickCraver commented Jan 31, 2016

@jasonwilliams200OK let me clarify, I really meant DirectoryServices.ActiveDirectory specifically. I think authentication, and the stuff around it: e.g. group membership is the 95-99% use case of the namespace. I think a direct port of signatures of that is pretty useful. If the rest warrants change for some reason then I'd be pretty okay with that, and okay if it came later...the auth would be good to get out the door ASAP since that's a blocker to many.

@saf-itpro

This comment has been minimized.

saf-itpro commented Feb 6, 2016

Integrating at least a basic functionality of searching Active Directory users and mapping them with custom roles with ASP.NET 5 will ease the implementation of Windows Authentication into ASP.NET web applications. We need this functionality at our intranet site.

@Sjark

This comment has been minimized.

Sjark commented Feb 8, 2016

This is a blocker for us as well. We need to be able to auth, query users and groups, create new user and groups etc against a ldap server.

@SSiefert

This comment has been minimized.

SSiefert commented Feb 8, 2016

It is also a blocker for me - I require quering and authenticating users.

@ClintBailiff

This comment has been minimized.

ClintBailiff commented Feb 19, 2016

I came up with a solution for authenticating against Active Directory in a .NET Core rc1 web application. You just have to override the CheckPasswordAsync method in the UserManager class. Let me know what you think.

First you need make a custom register page that allows the user to input an AD username instead of an email address and password. That username goes in the UserName property of the ApplicationUser class that is generated by the ASP.NET 5 template when you chose Individual User Accounts authentication. Also, you'll have to default the Password property to something that passes the internal validation in the IdentityUser class.

My register page controller calls a Web API 2 method that finds the username in AD and returns JSON that holds the AD information for that user. I've added some custom properties to the ApplicationUser class to hold the AD information. I will post the code from my project next week.

Then add a class file in the Services folder. I named mine ApplicationUserManager.cs. Add the code below to that class file.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.OptionsModel;
using [YourApp].Models;

namespace [YourApp].Services
{
    public class ApplicationUserManager : UserManager<ApplicationUser>
    {
        public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher,
                                      IEnumerable<IUserValidator<ApplicationUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators,
                                      ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger,
                                      IHttpContextAccessor contextAccessor)
        : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger, contextAccessor)
        {

        }

        public override async Task<bool> CheckPasswordAsync(ApplicationUser user, string password)
        {
            //Pass user.UserName and password to an ASP.NET Web API 2 method that 
            //does the Active Directory authentication and returns a bool.
        }
    }
}

Then open the Startup.cs file. Add .AddUserManager() to the AddIdentity call in the ConfigureServices method as shown below.

services.AddIdentity<ApplicationUser, IdentityRole>()
       .AddEntityFrameworkStores<ApplicationDbContext>()
       .AddUserManager<ApplicationUserManager>()
       .AddDefaultTokenProviders();

This at least allows me to setup policy/claims based authorization while waiting for DirectoryServices support.

@HB-2012

This comment has been minimized.

HB-2012 commented Feb 29, 2016

I rely on this library. It's a shame I can't port now.

@NickCraver

This comment has been minimized.

Member

NickCraver commented Apr 16, 2016

@ClintBailiff I have to chime in here - because relaying the user's password across the wire again to another application in plaintext is a really bad idea. Please, don't use this approach. It's a security hole.

@terrajobst this will be the blocker in porting my larger applications like Opserver over - can we please get this prioritized?

@ClintBailiff

This comment has been minimized.

ClintBailiff commented Apr 16, 2016

@NickCraver I never suggested passing the credentials as plaintext. As a rule I use SSL for all my web applications/services because they typically return data that only authorized users should see. I didn't think to specify that probably because it's so obvious that you would not want to send credentials in plaintext.

@PleasantD

This comment has been minimized.

PleasantD commented Apr 18, 2016

I would be i support of at least providing a port of System.DirectoryServices.Protocols. We recently switched our LDAP-related code to this to support a larger range of LDAP servers, as the System.DirectoryServices.ActiveDirectory namespace only likes to talk to AD servers.

I suppose, it would be possible for a 3rd party library to spin up this kind of support, but since it already exists in the framework I would imagine that a port would be simpler.

@aminebizid

This comment has been minimized.

aminebizid commented Apr 28, 2016

WTF asp team is not provide this basic functionality
This is a really blocker issue :(

@euclid47

This comment has been minimized.

euclid47 commented Oct 24, 2017

@karelz Where is the voting for this feature? I absolutely agree with @shairozan with the need. There is a comment in this issue that describes our development and production environment. It is quite shocking there has not been any movement on the implementation since .Net Core evangelists preach it is platform agnostic.

@karelz

This comment has been minimized.

Member

karelz commented Oct 24, 2017

I created a new issue to track the Linux/Mac port #24843 for easier voting than on the comment in the middle of this issue (#2089 (comment)).

I added the link also into the top post of this issue.

@euclid47 the voting so far was in this issue - see the links above. That's what resulted in the 7 votes (+1 for original issue submitter).

@balkarov

This comment has been minimized.

balkarov commented Oct 24, 2017

Our team needs support LDAP on Linux.
Because most of our clients use auth via LDAP.

@shairozan

This comment has been minimized.

shairozan commented Oct 24, 2017

@balkarov If you can, upvote on the the issue @karelz had just created ( #24843 )

@OskarKlintrot

This comment has been minimized.

OskarKlintrot commented Oct 25, 2017

@balkarov @shairozan @euclid47 If you are not aware already there is the Novell.Directory.Ldap.NETStandard Nuget package that you can use to integrate LDAP into your projects. We are not advanced LDAP users, we just use it to validate credentials and get user information, but it works fine for us, both on 1.0 as well as 2.0 running on the dotnet core runtime docker image. It's not an official way but it gets the job done until there is a cross platform port of System.DirectoryServices.

@balkarov

This comment has been minimized.

balkarov commented Oct 25, 2017

@OskarKlintrot thanks. But this library does not support login without domain.
I create issue dsbenghe/Novell.Directory.Ldap.NETStandard#43
Can you help me resolve this problem?

@OskarKlintrot

This comment has been minimized.

OskarKlintrot commented Oct 25, 2017

I'm not part of that project or an advanced user but I'll take a look, see you there!

(We are not login in with a domain)

@danmosemsft danmosemsft changed the title from Support for System.DirectoryServices to Support for System.DirectoryServices for Windows Oct 26, 2017

@danmosemsft

This comment has been minimized.

Member

danmosemsft commented Oct 26, 2017

Given @karelz broke out an issue for Unix, I retitled this one for clarity.

@balkarov

This comment has been minimized.

balkarov commented Oct 27, 2017

@danmosemsft but issue has plan
Linux/Mac ports.

@karelz

This comment has been minimized.

Member

karelz commented Oct 27, 2017

@balkarov I have updated the plan to link to other tracking issues and removed check boxes for items which are tracked separately (broken out work) or do not block Windows work.

@PKGeorgiev

This comment has been minimized.

PKGeorgiev commented Nov 1, 2017

Will System.DS port be compatible with RODC servers (Read-Only Domain Controllers)?

@tarekgh tarekgh removed their assignment Nov 20, 2017

@tarekgh

This comment has been minimized.

Member

tarekgh commented Nov 20, 2017

@PKGeorgiev you should get the same System.DirectoryServices support we have in the full framework.

@karelz

This comment has been minimized.

Member

karelz commented Nov 20, 2017

The work on DirectoryServices for Windows is finished, closing the issue.
Note:

  • Final package publishing is tracked by #24909
  • Linux/Mac port is tracked separately by #24843

@karelz karelz closed this Nov 20, 2017

@JaedsonBarbosa

This comment has been minimized.

JaedsonBarbosa commented Mar 14, 2018

Hi, will this work in UWP?

@tarekgh

This comment has been minimized.

Member

tarekgh commented Mar 15, 2018

Hi, will this work in UWP?

No, it is supported only for net core apps running on Windows and full framework. if you use it in UWP or on Linux, you'll get a PlatformNotSupported exception.

@sscoleman

This comment has been minimized.

sscoleman commented Mar 15, 2018

I am using this code in a lambda function in AWS which runs on Linux in the background and I am getting this error. "System.DirectoryServices.AccountManagement is not supported on this platform."
I am using core 2.0

 public static List<string> GetGroups(string userName, string domainString)
        {
            List<string> result = new List<string>();
            List<GroupPrincipal> gprList = new List<GroupPrincipal>();
            // establish domain context
            PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain, null, domainString);

            // find your user
            UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);

            // if found - grab its groups
            if (user != null)
            {
                PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();

                // iterate over all groups
                foreach (Principal p in groups)
                {
                    // make sure to add only group principals
                    if (p is GroupPrincipal)
                    {
                        gprList.Add((GroupPrincipal)p);
                    }
                }
            }

            foreach (var gp in gprList)
            {
                result.Add(gp.Name);
            }

            return result;
        }
@tarekgh

This comment has been minimized.

Member

tarekgh commented Mar 15, 2018

@sscoleman Yes, this is not supported on Linux yet. It is supported on Windows only.

@euclid47

This comment has been minimized.

euclid47 commented Mar 15, 2018

@sscoleman there is an issue created on it, #24843. It was said there was not enough community interest in it with the exception this question comes up all the time. So now you are in a crap spot. You spent time implementing directory services and then find out Linux is supported. Now you ask yourself why is this being touted as platform agnostic if there are Windows only features.

@thedevopsmachine

This comment has been minimized.

thedevopsmachine commented Mar 15, 2018

It's fairly obvious if you look at the greater Microsoft strategy. Microsoft are throwing ALL of their development resources into Azure, and that includes Active Directory. Check out "What's new in 2016", it's mostly AzureAD/Hybrid investments. https://docs.microsoft.com/en-us/windows-server/identity/whats-new-active-directory-domain-services.

Microsoft is not investing in this library for Linux because they want everyone to move to Azure AD instead. It makes sense, why would you invest in something that you're trying to get customers to move away from?

You're doing something relatively simple though. You can use the Novel LDAP libraries, they work with AD and on .NET Core for Linux. You need to do the protocol work yourself, but it's not overly complex, and there's a lot of samples out there. The downside is that you need to manage binding yourself, which requires a user DN and password.

@terrajobst

This comment has been minimized.

Member

terrajobst commented Mar 15, 2018

System.DirectoryServices is currently a Windows-only API and it's part of the Windows Compatibility-Pack for .NET Core. In principle, we can make parts of System.DirectoryServices work on Linux but we haven't had the resources to do that yet. #24843 is tracking this work item.

Why are we allowing to install packages that will not work on Linux? The alternative would be to fork the API surface but that doesn't work well for all cases either and makes the overall system harder to code against. Of course, our choice isn't without problems either, as it can make it harder to predict whether code will work cross-platform or. We have a preview of a compatibility analyzer that gives you live feedback as you code.

See this video for more context on how we see the Windows Compatibility Pack and the cross-platform analyzer work hand-in-hand:

https://channel9.msdn.com/Events/Connect/2017/T123

@terrajobst

This comment has been minimized.

Member

terrajobst commented Mar 15, 2018

@thedevopsmachine

Microsoft is not investing in this library for Linux because they want everyone to move to Azure AD instead.

That's not how I see it. As you pointed out, we intend to make money via Azure. And Azure is a cloud platform that offers a wide variety of technologies and operating systems. We have no business interest to promote Windows in the cloud over Linux in the cloud. But of course, .NET has had a strong presence on Windows for 15 years. Making things fully functional across all operating systems takes time, but I honestly think most people following our open source efforts can see that we're not hamstringing Linux on purpose. It just takes time.

@liquidboy

This comment has been minimized.

liquidboy commented Mar 15, 2018

i agree with the approach with having a consistent api x-plat and x-framework, but it is soul destroying whenever ive encountered that dreaded error .. i feel for @sscoleman ...

@hchungi

This comment has been minimized.

hchungi commented Aug 8, 2018

Can this DirectoryServices package work on CentOS 7?

@tarekgh

This comment has been minimized.

Member

tarekgh commented Aug 8, 2018

Can this DirectoryServices package work on CentOS 7?

The package can be installed but will not work. when using it you'll get platform not supported exception. we are looking how we can support directory services in general on Linux. this is on our radar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment