Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Verifying User is Part of Active Directory Group aspx page

Posted on 2013-11-15
7
Medium Priority
?
559 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:Carla Romere
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
7 Comments
 
LVL 29

Expert Comment

by:Paul Jackson
ID: 39653437
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
ID: 39655787
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:Carla Romere
ID: 39667229
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:Carla Romere
ID: 39667283
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:Carla Romere
ID: 39667295
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:
Carla Romere earned 0 total points
ID: 39786686
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:Carla Romere
ID: 39796434
I need to cancel this ticket as we've hired a developer to come in and help me get these resolved.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
Problem Hi all,    While many today have fast Internet connection, there are many still who do not, or are connecting through devices with a slower connect, so light web pages and fast load times are still popular.    If your ASP.NET page …
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…

593 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