1

I need to implement authentication using Active Directory for my Winforms application.

I know that it is possible to get current Windows user credential like this:

       AppDomain currentDomain = AppDomain.CurrentDomain;
        // Set the principal policy to WindowsPrincipal.
        currentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

But I need that system asks user to either:

  • select logged in credentials => this would be possible with PrincipalPolicy.WindowsPrincipal I guess
  • choose to enter different credentials in Windows login form (not in my application) => how can I get this working?

P.S. I know it is possible to send username/password like it is described here: Validate a username and password against Active Directory? but I don't want to have user credentials going through my application because off security risks

I found out also this project in CodeProject.com on how to authenticate against Active Directory using LDAP, but this also requires entering user credentials in my application...

I know that there is also Active Directory Federated Services, but as far as I know it is for Web based authentication...

Any solutions for desktop authentication against Active Directory?

Prokurors
  • 2,458
  • 3
  • 40
  • 65
  • 1
    Sounds like an odd requirement, and breaks a few principles (i.e. to log on as the other user, you need to know both - one to log on to the operating system, and the other to log in to the application) – Rowland Shaw Dec 11 '17 at 15:42
  • It's possible that more than one user is working with the system (I know - it is also odd) at once – Prokurors Dec 11 '17 at 15:52
  • I really don't understand the problem. You ask the user for username and password, and authenticate with that data using LDAP, that's how it's done. What's the problem with that? – Pikoh Dec 11 '17 at 15:53
  • @Pikoh I don't want user to enter his password in my user form - I think it always presents some security risks. I just want to trigger Windows authentication and then get back information about authenticated user – Prokurors Dec 11 '17 at 15:54
  • Then, don't ask for anything. If the user is logged to windows, use his credentials as he already logged in to windows – Pikoh Dec 11 '17 at 15:56
  • @Pikoh yes, for already logged in user - should be ok. But one usecase is when Trainee is logged - then his mentor should also authorize him by logging as additional user. It's very similar to the case when regular Windows user needs to install something - Windows access to enter credential for Administrator – Prokurors Dec 11 '17 at 16:04
  • 1
    @RowlandShaw I dont think it is odd requirement, there are circumstances that a user needs to log in with his user profile of the system from a colleague computer. – Jonathan Applebaum Dec 11 '17 at 19:44
  • @jonathana that's what "switch user" is for. There are all sorts of security implications with sharing log-ons (some which can infringe the law, depending on what sort of things the users in question have access to). Of course, if you really have to have this, the OS always has the "run as" functionality, so the app doesn't need to do this as well – Rowland Shaw Dec 12 '17 at 13:13
  • 1
    @RowlandShaw In my opinion, "switch user" is a bulky solution. the computing environment in the organization needs to adapt to the needs of the users and not vice versa, after all the work needs to be carried out efficiently and quickly to meet the organizational requirements. The programmer's job is to make sure everything is secure, but it's no longer an argument in programming that's already leaking into other areas, so the debate is futile. – Jonathan Applebaum Dec 12 '17 at 18:11

1 Answers1

3

Here is a method I wrote in VB.NET in the past, and converted to C# for you.
use System.DirectoryServices namespace (you need to make a reference) in order to check credentials of user against DC(LDAP) server in your network (windows network of course).

clarification: this method was requested by our company security department for circumstances that user need to log in to company software from a colleague computer.
i recommend (for security reasons) to require from your IT department to add all users to a specific active directory group and check also if the user is a member of this AD group, also record every local ip address that connects to the software.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.DirectoryServices;

namespace WindowsFormsApplication15
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (IsAuthenticated("YOUR DOMAIN", "USERNAME", "PASSWORD") == false)
            {
                // not exist in active directory!
            }
            else
            {
                // user is exist in active directory
            }
        }

        private string _path { get; set; }
        private string _filterAttribute { get; set; }

        public bool IsAuthenticated(string domain, string username, string pwd)
        {
            string domainAndUsername = domain + "\\" + username;
            DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
            try
            {
                object obj = entry.NativeObject;
                DirectorySearcher search = new DirectorySearcher(entry);
                search.Filter = "(SAMAccountName=" + username + ")";
                search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();
                if ((result == null))
                {
                    return false;
                }

                _path = result.Path;
                _filterAttribute =  result.Properties["cn"][0].ToString();

            }
            catch (Exception ex)
            {
                return false;
            }

            return true;
        }
    }
}
Jonathan Applebaum
  • 5,738
  • 4
  • 33
  • 52
  • Thanks for the answer, but this solution requires that user enters his AD password in my application... (well, I know that I can trust myself, but in case of security audit - this (leaking AD credentials to 3rd party (my) application) would not be accepted I think). For Azure AD there is Token based authentication, I'm searching for something similar for Winforms+Active Directory combination – Prokurors Dec 12 '17 at 08:52
  • Is your winforms application has also a server side or its only a client side app? Is Everything communicating only inside the lan of the organisation or not? – Jonathan Applebaum Dec 12 '17 at 10:10
  • Client app is communicating with database on server, there are some Windows services hosted on server. I agree that business logic should be on server side, but how does this affect authorization? – Prokurors Dec 12 '17 at 10:49
  • if i get the architecture properly its possible to create a secured service on the application server side (WCF or something like that), the other application will pass user credentials to the server, server will check if authorized and will send it to your application. BTW, business logic don``t have to be on the server, In many cases run time will be more efficient on client machine, that is one of the pro`s of desktop app (that is why they invented angular...) – Jonathan Applebaum Dec 12 '17 at 12:30