Solved

Verifying User is Part of Active Directory Group aspx page

Posted on 2013-11-15
7
521 Views
Last Modified: 2014-01-21
I am trying to figure out how to test if a user is part of an AD security group and allowing access to specific page content if they are. I found a script online at stackoverflow.com/questions/2188954/see-if-user-is-part-of-active-directory-group-in-c-sharp-asp-net, but I'm getting an error and can't figure out how to fix the error. THIS IS THE UNMODIFIED SCRIPT
public bool IsUserInSecurityGroup(string user, string group)
    {
        return IsUserInGroup(user, group, "tokenGroups");
    }
    public bool IsUserInAllGroup(string user, string group)
    {
        return IsUserInGroup(user, group, "tokenGroupsGlobalAndUniversal");
    }

    private bool IsUserInGroup(string user, string group, string groupType)
    {
        var userGroups = GetUserGroupIds(user, groupType);
        var groupTokens = ParseDomainQualifiedName(group, "group");
        using (var groupContext = new PrincipalContext(ContextType.Domain, groupTokens[0]))
        {
            using (var identity = GroupPrincipal.FindByIdentity(groupContext, IdentityType.SamAccountName, groupTokens[1]))
            {
                if (identity == null)
                    return false;

                return userGroups.Contains(identity.Sid);
            }
        }
    }
    private List<SecurityIdentifier> GetUserGroupIds(string user, string groupType)
    {
        var userTokens = ParseDomainQualifiedName(user, "user");
        using (var userContext = new PrincipalContext(ContextType.Domain, userTokens[0]))
        {
            using (var identity = UserPrincipal.FindByIdentity(userContext, IdentityType.SamAccountName, userTokens[1]))
            {
                if (identity == null)
                    return new List<SecurityIdentifier>();

                var userEntry = identity.GetUnderlyingObject() as DirectoryEntry;
                userEntry.RefreshCache(new[] { groupType });
                return (from byte[] sid in userEntry.Properties[groupType]
                        select new SecurityIdentifier(sid, 0)).ToList();
            }
        }
    }
    private static string[] ParseDomainQualifiedName(string name, string parameterName)
    {
        var groupTokens = name.Split(new[] {"\\"}, StringSplitOptions.RemoveEmptyEntries);
        if (groupTokens.Length < 2)
            throw new ArgumentException(Resources.Exception_NameNotDomainQualified + name, parameterName);
        return groupTokens;
    }

Open in new window

THIS IS THE SCRIPT WITH THE CHANGES I THINK I NEED TO MAKE:
        public bool IsUserInSecurityGroup(string user, string group)
        {
            return IsUserInGroup(user, group, "tokenGroups");
        }

        public bool IsUserInAllGroup(string user, string group)
        {
            return IsUserInGroup(user, group, "tokenGroupsGlobalAndUniversal");
        }

        private bool IsUserInGroup(string user, string group, string groupType)
        {
            var userGroups = GetUserGroupIds(user, groupType);
            var groupTokens = ParseDomainQualifiedName(group, "msds");
            using (var groupContext = new PrincipalContext(ContextType.Domain, groupTokens[0]))
            {
                using (var identity = GroupPrincipal.FindByIdentity(groupContext, IdentityType.SamAccountName, groupTokens[1]))
                {
                    if (identity == null)
                        return false;

                    return userGroups.Contains(identity.Sid);
                }
            }
        }

        private List<SecurityIdentifier> GetUserGroupIds(string user, string groupType)
        {
            var userTokens = ParseDomainQualifiedName(user, "user");
            using (var userContext = new PrincipalContext(ContextType.Domain, userTokens[0]))
            {
                using (var identity = UserPrincipal.FindByIdentity(userContext, IdentityType.SamAccountName, userTokens[1]))
                {
                    if (identity == null)
                        return new List<SecurityIdentifier>();

                    var userEntry = identity.GetUnderlyingObject() as DirectoryEntry;
                    userEntry.RefreshCache(new[] { groupType });
                    return (from byte[] sid in userEntry.Properties[groupType]
                            select new SecurityIdentifier(sid, 0)).ToList();
                }
            }
        }

        private static string[] ParseDomainQualifiedName(string name, string parameterName)
        {
            var groupTokens = name.Split(new[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
            if (groupTokens.Length < 2)
                throw new ArgumentException(Resources.Exception_NameNotDomainQualified + name, parameterName);
            return groupTokens;
        }

Open in new window

I changed line 14 and put in the name of the security group to which I'm testing. On line 29, "user" I think is where should be the currently logged in user. The error I see is on line 46 and the word "Resources" has the red squiggly line underneath with the error message: "The name 'Resources' does not exist in the current context." This looks like it should be straightforward, but I don't know if I'm missing a reference call or what. The script we use currently to get the logged in user is this:
        string LoggedOnUser;  // NT userid
        System.Type oType = System.Type.GetTypeFromProgID("Wscript.Network");
        object pc = System.Activator.CreateInstance(oType);

        //Get NT userid data
        LoggedOnUser = Request.ServerVariables["AUTH_USER"];

        int pos = LoggedOnUser.IndexOf('\\');
        if (pos > 0)
        {
            LoggedOnUser = LoggedOnUser.Substring(pos + 1);
        }

        if ( LoggedOnUser == "cromer" || LoggedOnUser == "spore" || LoggedOnUser == "rshields" || LoggedOnUser == "medwar" || LoggedOnUser == "dander" || LoggedOnUser == "bnovil")
        {
            admin.Visible = true;
        }

Open in new window

This works, but I want to control permissions on this page at the AD level instead of having to add specific users to this page to give them permissions.
0
Comment
Question by:Hers2keep
  • 5
7 Comments
 
LVL 29

Expert Comment

by:Paul Jackson
Comment Utility
Resources. is a way of linking to a resource file contained in a project, if you haven't added a resource file to the project this is why you would see the error. All that is doing is getting some text for an error message from a resources file so you could replace Resources.Exception_NameNotDomainQualified with a text string something like 'Username has no domain prefix", which would change :

throw new ArgumentException(Resources.Exception_NameNotDomainQualified + name, parameterName);

to:

throw new ArgumentException("Username has no domain prefix," + name, parameterName);
0
 
LVL 11

Expert Comment

by:SAMIR BHOGAYTA
Comment Utility
hi.. this is useful for you.....

''' <summary>
''' Function to return all the groups the user is a member od
''' </summary>
''' <param name="_path">Path to bind to the AD</param>
''' <param name="username">Username of the user</param>
''' <param name="password">password of the user</param>
Private Function GetGroups(ByVal _path As String, ByVal username As String, _
                 ByVal password As String) As Collection
    Dim Groups As New Collection
    Dim dirEntry As New _
        System.DirectoryServices.DirectoryEntry(_path, username, password)
    Dim dirSearcher As New DirectorySearcher(dirEntry)
    dirSearcher.Filter = String.Format("(sAMAccountName={0}))", username)
    dirSearcher.PropertiesToLoad.Add("memberOf")
    Dim propCount As Integer
    Try
        Dim dirSearchResults As SearchResult = dirSearcher.FindOne()
        propCount = dirSearchResults.Properties("memberOf").Count
        Dim dn As String
        Dim equalsIndex As String
        Dim commaIndex As String
        For i As Integer = 0 To propCount - 1
            dn = dirSearchResults.Properties("memberOf")(i)
            equalsIndex = dn.IndexOf("=", 1)
            commaIndex = dn.IndexOf(",", 1)
            If equalsIndex = -1 Then
                Return Nothing
            End If
            If Not Groups.Contains(dn.Substring((equalsIndex + 1), _
                                  (commaIndex - equalsIndex) - 1)) Then
                Groups.Add(dn.Substring((equalsIndex + 1), & _
                                       (commaIndex - equalsIndex) - 1))
            End If
        Next
    Catch ex As Exception
        If ex.GetType Is GetType(System.NullReferenceException) Then
            MessageBox.Show("Selected user isn't a member of any groups " & _
                            "at this time.", "No groups listed", _
                            MessageBoxButtons.OK, MessageBoxIcon.Error)
            'they are still a good user just does not
            'have a "memberOf" attribute so it errors out.
            'code to do something else here if you want
        Else
            MessageBox.Show(ex.Message.ToString, "Search Error", & _
 MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Try
    Return Groups
End Function
End Class
0
 

Author Comment

by:Hers2keep
Comment Utility
I ended up getting this working by expanding on another stored procedure I had to display the users' groups. I will attach the stored procedures and my aspx code here.
GetLdapUserGroups.sql
aer-IsUserInGroup.sql
PageContent.txt
Page-LoadEvent.txt
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:Hers2keep
Comment Utility
Well, I lied. The above script works on some pages, but not others. I'm not sure why yet. I purposefully removed myself from an AD group, but the page still loads admin content for me.
0
 

Author Comment

by:Hers2keep
Comment Utility
Truly bizarre. Using the same script I uploaded, some security groups work with the code to prevent me from accessing what I want to protect. Other security groups do not. I can put in a group I've never been a member of and it stops me from seeing the content. But changing the group to a group I have been a member of, but am not currently, will still allow me to see the content.
0
 

Accepted Solution

by:
Hers2keep earned 0 total points
Comment Utility
I need to cancel this ticket as we've hired a developer to come in and help me get these resolved next week.
0
 

Author Closing Comment

by:Hers2keep
Comment Utility
I need to cancel this ticket as we've hired a developer to come in and help me get these resolved.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now