1
votes

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?

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
It's possible that more than one user is working with the system (I know - it is also odd) at onceProkurors
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
@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.jonathana
@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.jonathana

1 Answers

3
votes

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;
        }
    }
}