C# での Active Directory に対するユーザー認証

Syed Hassan Sabeeh Kazmi 2023年10月12日
  1. System.DirectoryServices.AccountManagement 名前空間を使用して、C# で Active Directory に対してユーザーを検証する
  2. System.DirectoryServices 名前空間を使用して、C# で Active Directory に対してユーザーを検証する
  3. System.DirectoryServices.Protocols 名前空間を使用して、C# で Active Directory に対してユーザーを検証する
  4. C#ActiveDirectoryMembershipProvider.ValidateUser(String, String) メソッドを使用して AD に対してユーザーを検証する
C# での Active Directory に対するユーザー認証

指定されたユーザー情報に基づいて資格情報を検証し、その結果を call メソッドに返すことで、Active Directory に対するアカウント認証が可能になります。 このチュートリアルでは、C# で Active Directory に対してユーザーを認証または検証する 4つの方法について説明します。

System.DirectoryServices.AccountManagement 名前空間を使用して、C# で Active Directory に対してユーザーを検証する

ユーザー資格情報を確認または検証できる .NET 3.5 以降のバージョンで作業する場合、最も簡単な方法の 1つです。 この名前空間の主な目標は、基本的な管理操作を簡素化し、基礎となるディレクトリに関係なく一貫性を持たせ、これらの操作に信頼できる結果を提供することです。

一般に、ディレクトリベースのアプリケーションを構築する C# 開発者は、多くの場合、Active Directory に保存されているユーザーの資格情報を認証する必要があり、内部で LDAP バインド操作を強制するために DirectoryEntry クラスを使用してこのタスクを実行します。

セキュリティで保護されていない貧弱な C# コードを作成するのは非常に簡単であるため、開発者は安全性の高いコードを作成するように注意する必要があります。 Active Directory 固有の制限を克服できますが、より複雑な C# コードを作成する必要があります。

コード例:

using System;
using System.Windows.Forms;
using System.DirectoryServices.AccountManagement;

namespace activeDirectoryAuthentication {
  public partial class Form1 : Form {
    string username, password;
    public Form1() {
      InitializeComponent();
    }

    // insert username in textfield by user
    private void textBox1_TextChanged(object sender, EventArgs e) {
      username = textBox1.Text;
    }

    // insert password in textfield by user
    private void textBox2_TextChanged(object sender, EventArgs e) {
      password = textBox2.Text;
    }

    // click event after the user clicks `Login`
    private void button1_Click(object sender, EventArgs e) {
      try {
        // create a connection to domain, no need to add or mention LDAP:// in domain
        using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "yourdomain.com")) {
          // validate the credentials
          bool isValid = pc.ValidateCredentials(username, password);
          if (isValid) {
            // User credentials validated
          } else {
            // Not authenticated
          }
        }
      } catch (Exception ex) {
        // throw an exception when a connection to the domain is unsuccessful
      }
    }
  }
}

System.DirectoryServices 名前空間を使用して、C# で Active Directory に対してユーザーを検証する

Active Directory ドメイン サービスへの簡単なアクセスを提供し、Active Directory サービス インターフェイス テクノロジを使用するための DirectorySearcherDirectoryEntry の 2つの主要なコンポーネント クラスが含まれています。 サイズに関係なく、ネットワーク上のリソースを見つけて管理することにより、Active Directory に対してユーザーを簡単に検証します。

アプリケーションが単一のインターフェースを使用して、インターネット上のさまざまな方向と対話できるようにします。 各ノードが一連のプロパティを表すツリー構造を使用し、ツリーの検索、トラバース、編集、およびノードのプロパティの読み取り/書き込みに使用できます。

DirectoryEntry クラスは、AD ドメイン サービス階層のノードをカプセル化し、オブジェクトのバインド、プロパティの読み取り、属性またはユーザー アカウントの更新を行うことができます。 DirectorySearcher クラスを使用して Active Directory に対してクエリを実行し、ユーザーを検証および認証します。

コード例:

using System;
using System.Windows.Forms;
using System.DirectoryServices;

namespace activeDirectoryAuthentication {
  public partial class Form1 : Form {
    string username, password;
    public Form1() {
      InitializeComponent();
    }

    // insert username in textfield by user
    private void textBox1_TextChanged(object sender, EventArgs e) {
      username = textBox1.Text;
    }

    // insert password in textfield by user
    private void textBox2_TextChanged(object sender, EventArgs e) {
      password = textBox2.Text;
    }

    // click event after the user clicks `Login`
    private void button1_Click(object sender, EventArgs e) {
      IsValidUser(username, password);
    }

    private bool IsValidUser(string username, string password) {
      bool isValid = false;
      try {
        DirectoryEntry entry = new DirectoryEntry("LDAP://yourdomain.com", username, password);
        object nativeObj = entry.NativeObject;
        isValid = true;
      } catch (DirectoryServicesCOMException comex) {
        // Not Authenticated. comex.Message will return the reason
      } catch (Exception ex) {
        // optional
      }
      return isValid;
    }
  }
}

System.DirectoryServices.Protocols 名前空間を使用して、C# で Active Directory に対してユーザーを検証する

Active Directory に対してユーザーを検証する他の方法とは異なり、変更が必要なパスワードと間違ったパスワードを持つユーザーを区別できます。 ユーザー パスワードの変更が必要な場合、または存在しない場合は、例外が表示されます。

lexc.ServerErrorMessage を使用して、データ値が Win32 Error コードの 16 進表現である例外をスローします。 lexc.ServerErrorMessage に含まれるエラー コードは同じで、それ以外の場合は Win32 LogonUser API 呼び出しを呼び出すことによって返されます。

C# の System.DirectoryServices.Protocols 名前空間は、LDAP バージョン 3 および DSML バージョン 2.0 標準で定義されたメソッドを提供します。 LdapConnection クラスを利用して、Active Directory への TCP/IP または UDP LDAP 接続を作成し、ユーザーを認証します。

コード例:

using System;
using System.Net;
using System.Windows.Forms;
using System.DirectoryServices.Protocols;

namespace activeDirectoryAuthentication {
  public partial class Form1 : Form {
    string username, password;
    public Form1() {
      InitializeComponent();
    }

    // insert username in textfield by user
    private void textBox1_TextChanged(object sender, EventArgs e) {
      username = textBox1.Text;
    }

    // insert password in textfield by user
    private void textBox2_TextChanged(object sender, EventArgs e) {
      password = textBox2.Text;
    }

    // click event after the user clicks `Login`
    private void button1_Click(object sender, EventArgs e) {
      try {
        LdapConnection adDatabaseCon = new LdapConnection("LDAP://enteryourdomainaddress.com");
        NetworkCredential credential = new NetworkCredential(username, password);
        adDatabaseCon.Credential = credential;
        adDatabaseCon.Bind();
        MessageBox.Show("You are logged in successfully!");
      } catch (LdapException lexc) {
        String error = lexc.ServerErrorMessage;
        // MessageBox.Show(lexc);
      } catch (Exception exc) {
        // MessageBox.Show(exc);
      }
    }
  }
}

C#ActiveDirectoryMembershipProvider.ValidateUser(String, String) メソッドを使用して AD に対してユーザーを検証する

System.Web.Security 名前空間に属し、その主な目的は、Active Directory で指定されたユーザー名とパスワードを確認または検証することです。 これには 2つのパラメーターがあり、最初のパラメーターは username 文字列で、もう 1つは指定されたユーザーのパスワードを表す password 文字列です。

このメソッドはブール値を true または false として返します。 true は有効なユーザーを表し、ユーザーが Active Directory に存在しない場合、ValidateUser(String, String) メソッドは false を返します。

Membership クラスはこのメソッドを呼び出して、AD に対してユーザー資格情報を検証します。正しい資格情報が提供された場合でも false を返す場合は、その理由も明らかにします。 ユーザーを検証する場合、プロバイダーは、アプリケーションの構成ファイルで構成された資格情報ではなく、指定されたユーザー名とパスワードを使用して Active Directory に接続することにより、資格情報を検証します。

ただし、ActiveDirectoryMembershipProvider インスタンスは、構成された資格情報を使用してディレクトリに接続し、ユーザーが検索範囲内に存在することを確認し、EnablePasswordReset プロパティが true であることを確認し、構成された資格情報を使用して ユーザー インスタンス。

コード例:

using System;
using System.Windows.Forms;
using System.Web.Security;  // moved in System.Web.ApplicationServices

namespace activeDirectoryAuthentication {
  public partial class Form1 : Form {
    string username, password;
    bool publicC;
    public Form1() {
      InitializeComponent();
    }

    // insert username in textfield by user
    private void textBox1_TextChanged(object sender, EventArgs e) {
      username = textBox1.Text;
    }

    // insert password in textfield by user
    private void textBox2_TextChanged(object sender, EventArgs e) {
      password = textBox2.Text;
    }

    // to check if the account is a public account or an admin account
    private void radioButton1_CheckedChanged(object sender, EventArgs e) {
      publicC = radioButton1.Checked;
    }

    // click event after the user clicks `Login`
    private void button1_Click(object sender, EventArgs e) {
      // use `ActiveDirectoryMembershipProvider` as the default membership provider
      var adok = Membership.Provider.ValidateUser(username, password);

      if (Membership.ValidateUser(username, password)) {
        FormsAuthentication.RedirectFromLoginPage(username, publicC);
      } else
        MessageBox.Show("Login failed. Please check your user name and password and try again.");
    }
  }
}

Active Directory 認証は、ユーザーのサインイン エクスペリエンスを簡素化し、セキュリティを最大化することで攻撃のリスクを軽減します。 Active Directory の助けを借りて、オンプレミスのデバイスと C# アプリケーションでユーザーの更新された資格情報を使用して、アカウントをすぐに検証できます。

Microsoft の Active Directory は IT インフラストラクチャの重要な部分であり、適切な方法でアクセスしないと、IT 環境全体が危険にさらされる可能性があります。 このチュートリアルでは、C# で Active Directory に対してユーザー/アカウントを検証または認証するための最適化された方法を学習しました。

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub

関連記事 - Csharp Authentication