Click here to Skip to main content
15,891,184 members
Articles / Programming Languages / C#

Active Directory with ASP.NET MVC (.NET)

Rate me:
Please Sign up or sign in to vote.
4.25/5 (8 votes)
7 Mar 2019CPOL1 min read 48.1K   24   15
Active Directory with ASP.NET MVC

Introduction

When it comes to access Microsoft's Active Directory using C#, a lot of people get confused how to get started. This article attempts to show you how to communicate with active directory using C# in a simple way. I make a simple web application interact with active directory using ASP.NET MVC .This application performs only three operations on active directory:

  • get all users
  • get all groups
  • reset password for users

Background

You should have some basic knowledge with ASP.NET MVC.

Active Directory

  1. Install Windows Server 2012 R2.
  2. Install Active Directory Domain Service.
  3. Create new domain in a new forest. I named it “MBS.Com”.
  4. Add organizational unit and named it “DevOU.
  5. Add some users and groups in OU.

Image 1

Using the Code

There are two namespaces to communicate Active Directory with C#:

  1. System.DirectoryServices.ActiveDirectory
  2. System.DirectoryServices.AccountManagement (this is what I used)

Note

In my case, IIS server and directory domain controller reside on the same machine to run task successfully.

  • Add Action called HomePage in your Controller containing two buttons, one for Users and other for Groups.
    C#
    public ActionResult HomePage()
       {
           return View();
       }
    
  • Add View for this Action:
    HTML
    @{
        ViewBag.Title = "HomePage";
    }
    @*<h2>HomePage</h2>*@
    <br />
    <br />
    <div class="row text-center">
        <div class="col lg-6">
            @Html.ActionLink
             ("Users", "GetAllUsers", "Home", null, new { @class = "btn btn-primary" })
            @Html.ActionLink
             ("Groups", "GetAllGroups", "Home", null, new { @class = "btn btn-primary" })
        </div>
    </div>

    Image 2

  • Add two Classes for User and Group in Models Folder:
    C#
    public class User
    {
        public int Id { get; set; }
        [Display(Name = "Display Name")]
        public string DisplayName { get; set; }
        public string Samaccountname { get; set; }
    }
    
    public class Group
    {
        public int Id { get; set; }
        [Display(Name = "Group Name")]
        public string GroupName { get; set; }
    }
    
  • Then we will implement three methods which will be performed on Active Directory: Get All Users, Get All Groups, Set Password:
    C#
          public ActionResult GetAllUsers()
            {
                List<User> ADUsers = GetallAdUsers();
                return View(ADUsers);
            }
    
            public ActionResult GetAllGroups()
            {
                List<Group> ADGroups = GetallGroups();
                return View(ADGroups);
            }
    
            //if you want to get Groups of Specific OU you have to add OU Name in Context        
            public static List<User> GetallAdUsers()
            {
                List<User> AdUsers = new List<User>();
                //MBS.com My Domain Controller which i created 
                //OU=DevOU --Organizational Unit which i created 
                //and create users and groups inside it 
                var ctx = new PrincipalContext(ContextType.Domain, "MBS","OU=DevOU,DC=MBS,DC=com");
                UserPrincipal userPrin = new UserPrincipal(ctx);
                userPrin.Name = "*";
                var searcher = new System.DirectoryServices.AccountManagement.PrincipalSearcher();
                searcher.QueryFilter = userPrin;
                var results = searcher.FindAll();
                foreach (Principal p in results)
                {
                    AdUsers.Add(new User { DisplayName = p.DisplayName, 
                                           Samaccountname = p.SamAccountName });
                }
                return AdUsers;
            }
    
            public ActionResult ResetPassword(string Samaccountname)
            {
                //i get the user by its SamaccountName to change his password
                PrincipalContext context = new PrincipalContext
                                           (ContextType.Domain, "MBS", "OU=DevOU,DC=MBS,DC=com");
                UserPrincipal user = UserPrincipal.FindByIdentity
                                     (context, IdentityType.SamAccountName, Samaccountname);
                //Enable Account if it is disabled
                user.Enabled = true;
                //Reset User Password
                string newPassword = "P@ssw0rd";
                user.SetPassword(newPassword);
                //Force user to change password at next logon dh optional
                user.ExpirePasswordNow();
                user.Save();
                TempData["msg"] = "<script>alert('Password Changed Successfully');</script>";
                return RedirectToAction("GetAllUsers");
            }
    
            //if you want to get all Groups of Specific OU you have to add OU Name in Context 
            public static List<Group> GetallGroups()
            {  
                List<Group> AdGroups = new List<Group>();
                var ctx = new PrincipalContext(ContextType.Domain, "MBS", "OU=DevOU,DC=MBS,DC=com");
                GroupPrincipal _groupPrincipal = new GroupPrincipal(ctx);
    
                PrincipalSearcher srch = new PrincipalSearcher(_groupPrincipal);
    
                foreach (var found in srch.FindAll())
                {
                    AdGroups.Add(new Group { GroupName = found.ToString() });
                              
                }
                return AdGroups;
            }
  • Then Add view for GetAllUsers action.
    HTML
        @model IEnumerable<ActiveDirectory.Models.User>
    @{
        ViewBag.Title = "GetAllUsers";
    }
    
    <br />
    
    <form>
        <div class="form-group">
            <label for="SearchInput" class="col-sm-2 col-form-label">Search for User</label>
            <div class="col-md-10">
                <input type="text" class="form-control" id="SearchInput" 
                 onkeyup="myFunction()" placeholder="Enter User">
            </div>
        </div>
    </form>
    
    <br />
    <br />
    @Html.Raw(TempData["msg"])
    
        <table class="table table-bordered table-striped" id="tblUsers">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.DisplayName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Samaccountname)
                </th>
                <th></th>
            </tr>
    
            @foreach (var item in Model)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.DisplayName)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Samaccountname)
                    </td>
                    <td>
                        @Html.ActionLink("Reset Password", "ResetPassword", 
                                          new { Samaccountname = item.Samaccountname })
                    </td>
                </tr>
            }
    
        </table>
    
    @section scripts
    {
        <script>
    
    function myFunction() {
      var input, filter, table, tr, td, i;
      input = document.getElementById("SearchInput");
      filter = input.value.toUpperCase();
      table = document.getElementById("tblUsers");
      tr = table.getElementsByTagName("tr");
      for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[0];
        if (td) {
          if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
          } else {
            tr[i].style.display = "none";
          }
        }
      }
    }
    </script>
    }

    Image 3Image 4

  • Add another view for GetAllGroups Action.
    HTML
     @model IEnumerable<ActiveDirectory.Models.Group>
    @{
        ViewBag.Title = "GetAllGroups";
    }
    <br />
    
    <table class="table table-striped table-bordered">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.GroupName)
            </th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.GroupName)
            </td>
    
        </tr>
    }
    </table>

    Image 5

Notes

All these functionalities work on specific organizational unit I have created “DevOU”.
To get All Users and groups of Active Directory, just remove “OU” from path in the context.

Image 6

History

  • 7th March, 2019: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Egypt Egypt
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
PraiseGot it to work. Pin
Rene Vliex 202216-May-23 2:31
Rene Vliex 202216-May-23 2:31 
Questioncrud operations Pin
variety jones27-Apr-22 14:30
variety jones27-Apr-22 14:30 
BugMessage d'erreur du compilateur: CS0246 Pin
Member 1559544115-Apr-22 14:18
Member 1559544115-Apr-22 14:18 
Bugerreur pour view Pin
Member 1559544111-Apr-22 2:15
Member 1559544111-Apr-22 2:15 
GeneralRe: erreur pour view Pin
Richard MacCutchan11-Apr-22 2:19
mveRichard MacCutchan11-Apr-22 2:19 
QuestionRe: erreur pour view Pin
Member 1559544116-Apr-22 11:12
Member 1559544116-Apr-22 11:12 
AnswerRe: erreur pour view Pin
Rene Vliex 202215-May-23 23:04
Rene Vliex 202215-May-23 23:04 
QuestionFantastic Pin
marshallsoft28-Oct-21 19:03
marshallsoft28-Oct-21 19:03 
Questiongood job Pin
E Business24-Jun-21 7:24
E Business24-Jun-21 7:24 
Suggestionshare the code Pin
Fernando Rodríguez Acero23-May-20 7:26
Fernando Rodríguez Acero23-May-20 7:26 
QuestionUser Password Change Pin
Member 1231711925-Mar-20 3:16
Member 1231711925-Mar-20 3:16 
QuestionHow to add search criteria to find a specific group? Pin
Racer X Speedy30-May-19 9:12
Racer X Speedy30-May-19 9:12 
QuestionUnlock Windows with C# Pin
marti868-Mar-19 2:20
marti868-Mar-19 2:20 
QuestionIIS and DC Pin
nullpointer7-Mar-19 22:47
nullpointer7-Mar-19 22:47 
Hi,

I don't think it is a good idea to have your web application running on your domain controller.
{}*

AnswerRe: IIS and DC Pin
Rene Vliex 202215-May-23 22:59
Rene Vliex 202215-May-23 22:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.