?
Solved

Retrieve users Active Directory Group while using Forms Authentication

Posted on 2009-02-20
4
Medium Priority
?
951 Views
Last Modified: 2012-05-06
Hello,
I created a website that uses both Active Directory and SQL server to authenticate the user. The login is managed by the ASP.NET login control. At the moment an intranet user or an external user is able to log in successfully to my website and the external user that exists in the SQL server database can see things based on their role. The problem that I have is that there is no way to tell which group the Active Directory user belongs to. I was wondering if someone can post some code that would gather the role / group that the AD user belongs to when they log in. I have posted my web.config and the authenticate event from the Login.aspx.vb below. Any help or suggestions would be greatly appreciated!
Web.config
<authentication mode="Forms">
      <forms name=".ADAuthCookie" timeout="10"  />
    </authentication >
    <authorization>
      <deny users="?" />
      <allow users="*" />
    </authorization>
    <roleManager enabled="true" defaultProvider="SQLRoleManager">
      <providers>
        <add name="SqlRoleManager"
             type="System.Web.Security.SqlRoleProvider"
             connectionStringName="SqlUserConnection"
             applicationName="" />
</providers>
    </roleManager>
    <membership defaultProvider="MyADMembershipProvider" >
            <providers> 
             <add
           name="MyADMembershipProvider"
           type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, &#xD;&#xA; Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
           attributeMapUsername="sAMAccountName"
           connectionStringName="ADConnectionString"
           connectionUsername=""
           connectionPassword=""/>
              <add name="MySqlMembershipProvider"
         connectionStringName="SqlUserConnection"
         applicationName="TransferOfCare"
         requiresQuestionAndAnswer="False" 
         requiresUniqueEmail="False" 
         enablePasswordRetrieval="False"
          enablePasswordReset="True"
          passwordFormat="Hashed"
          maxInvalidPasswordAttempts="10"
          minRequiredPasswordLength="1"
          minRequiredNonalphanumericCharacters="0"
          passwordAttemptWindow="10"
         type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
            </providers>
    </membership>
 
Login.aspx.vb
    Protected Sub Login1_Authenticate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs) Handles Login1.Authenticate
        Dim sqlmp As MembershipProvider = Membership.Providers("MySqlMembershipProvider")
        If Membership.ValidateUser(Login1.UserName, Login1.Password) = True Then
            e.Authenticated = True
        ElseIf sqlmp.ValidateUser(Login1.UserName, Login1.Password) = True Then
            e.Authenticated = True
        Else
            e.Authenticated = False
        End If
    End Sub

Open in new window

0
Comment
Question by:CityGrl
  • 2
  • 2
4 Comments
 
LVL 1

Accepted Solution

by:
KCFORSYTHE earned 2000 total points
ID: 23694259
If LDAP is an option for you, here is a set of code I have used in the past that allows you to send in a domain, username, and password and it returns back a collection of group names that the user belongs to.

Kent

        Public Function GetUserGroups(ByVal UserName As String, ByVal Password As String, ByVal Domain As String) As Collection
            Dim RetGroups As New Collection
            Dim GrpName As String
            ' get the groups the user belongs to'
            Dim entry As New DirectoryEntry("LDAP://" & Domain, UserName, Password, System.DirectoryServices.AuthenticationTypes.Secure)
            Dim search As New DirectorySearcher(entry)
 
            search.Filter = "(&(objectClass=user)(sAMAccountName=" + _filterAttribute + "))"
 
            search.PropertiesToLoad.Add("memberOf")
 
            Dim groupNames As New System.Text.StringBuilder
 
            Try
                Dim result As SearchResult = search.FindOne()
                Dim propertyCount As Int32 = result.Properties("memberOf").Count
                Dim dn As String
                Dim equalsIndex As Int32, commaIndex As Int32
                Dim propertyCounter As Int32
 
                For propertyCounter = 0 To propertyCount - 1
                    dn = DirectCast(result.Properties("memberOf")(propertyCounter), String)
                    equalsIndex = dn.IndexOf("=", 1)
                    commaIndex = dn.IndexOf(",", 1)
                    If (-1 = equalsIndex) Then
                        GrpName = dn
                        RetGroups.Add(GrpName)
                    Else
                        GrpName = dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1)
                        RetGroups.Add(GrpName)
                    End If
 
                Next propertyCounter
 
            Catch ex As Exception
                Throw New Exception("Error obtaining group names. " + ex.Message)
            Finally
                entry.Dispose()
                entry = Nothing
                search = Nothing
            End Try
 
            Return RetGroups
 
        End Function

Open in new window

0
 

Author Comment

by:CityGrl
ID: 23696275
Thank you KCFORSYTHE! Your code works wonderfully!

Is there a way to tie the groups that the user has to the user object that the login controls use? I could add each user and their roles to my SQL datastore but I would rather not go that route. I could also do a look up each time I wanted to do something but that sounds like a lot of redundant calls.
0
 
LVL 1

Expert Comment

by:KCFORSYTHE
ID: 23711650
CityGrl,

Sorry for the delay in responding.  I'm not aware of a way to get it from the login control object.  If there is a way, I'd love to know it also.

Kent
0
 

Author Comment

by:CityGrl
ID: 23759584
Thanks KC! What I ended up doing was using part of your solution. This was not the ideal way to implement but it works! As I authenticate the AD user, I simply add the roles that I want to my SQL server role store and reference the roles from there. My code is below. THanks for your help!
    Public Function AuthenticateUser()
 
        Dim GrpName As String
 
        Dim entry As New DirectoryEntry("LDAP://address, DC=", username, password, System.DirectoryServices.AuthenticationTypes.Secure)
        Dim search As New DirectorySearcher(entry)
        Dim flag As Boolean = False
 
        search.Filter = "(&(objectClass=user)(sAMAccountName=" + Login1.UserName + "))"
 
        search.PropertiesToLoad.Add("memberOf")
 
        Dim groupNames As New System.Text.StringBuilder
 
        Try
            Dim result As SearchResult = search.FindOne()
            Dim propertyCount As Int32 = result.Properties("memberOf").Count
            Dim dn As String
            Dim equalsIndex As Int32, commaIndex As Int32
            Dim propertyCounter As Int32
 
            For propertyCounter = 0 To propertyCount - 1
                dn = DirectCast(result.Properties("memberOf")(propertyCounter), String)
                equalsIndex = dn.IndexOf("=", 1)
                commaIndex = dn.IndexOf(",", 1)
                If (-1 = equalsIndex) Then
                    GrpName = dn
                Else
                    GrpName = dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1)
                End If
 
 
                If GrpName = "grp1" Or GrpName = "grp2" Or GrpName = "grp3" Or GrpName = "grp4" Then
                    If Not (Roles.IsUserInRole(Login1.UserName, GrpName)) Then
                        Roles.AddUserToRole(Login1.UserName, GrpName)
                    End If
                End If
 
 
            Next propertyCounter
 
        Catch ex As Exception
            Throw New Exception("Error obtaining group names. " + ex.Message)
        Finally
            entry.Dispose()
            entry = Nothing
            search = Nothing
        End Try
 
 
        Return flag
    End Function

Open in new window

0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

Question has a verified solution.

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

Recently, Microsoft released a best-practice guide for securing Active Directory. It's a whopping 300+ pages long. Those of us tasked with securing our company’s databases and systems would, ideally, have time to devote to learning the ins and outs…
High user turnover can cause old/redundant user data to consume valuable space. UserResourceCleanup was developed to address this by automatically deleting user folders when the user account is deleted.
This tutorial will walk an individual through the steps necessary to join and promote the first Windows Server 2012 domain controller into an Active Directory environment running on Windows Server 2008. Determine the location of the FSMO roles by lo…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Suggested Courses

850 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