Asked by:
LDAP Query

Question
-
User1415440864 posted
Hello!
I need to use a LDAP query to check if the user is an admin of the web application from the AD. I am pretty much clueless with anything that pertains to the AD. it should be something like this:
SELECT ADsPath FROM LDAP://domainname/DC=""/DC="",DC="" WHERE samAccountName = "" & userID & AND objectCategory='Person'
Is this even close?
In the Log In page, the user types in two boxes their username and password and it checks if they are admin or not then direct them to the right page.
Admin=Propertylisting.aspx
Users = AddProperty.aspxI hope I am making any sense at all.
Thanks in advance!
Wednesday, August 16, 2006 6:05 PM
All replies
-
User1354132231 posted
If you are using System.DirectoryServices (which you should), you are way off (sorry!). SDS uses standard LDAP query format (e.g. "(&(objectCategory=person)(sAMAccountName={0}))"). However, even this is not the right choice here. If you are using Integrated Windows Auth (IWA), you should be using HttpContext.Current.User.IsInRole("rolename") here. Even if you were using custom authentication, you should be populating your principal object and using the IsInRole functionality.
I would recommend reading Fritz Onion's ASP.NET book (the new one coming or even the old one) for ASP.NET things like this. I would of course recommend my own book for learning how to interact with Active Directory using SDS. You can at least download the samples and a sample chapter to get more ideas on how this is done with SDS from the book's website (see the sticky post for more samples details).
Thursday, August 17, 2006 9:06 AM -
User1415440864 posted
Actually, I tried using the IsinRole but it seems to be not working. I have asked one of the admins if the group's name was correct. When I try to log in, it takes me to AddProperty instead of PropertyListing.aspx. Here is the code. Am I doing something wrong? Thank you.
Protected Sub btnLogIn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLogIn.Click
Dim Properties As String() = New String() {"sAMAccountName"}'verify user credentials against the active directory
Dim ADUser As SearchResult = FindADUser(Properties)If Not IsNothing(ADUser) Then
'if login names match, then authentication was succesful
If ADUser.Properties("sAMAccountName")(0).ToString.ToUpper = txtUserName.Text.ToUpper Then
If User.IsInRole("MAC/HW/MAC-ALL-RiskPropertyAdmins") Then
Response.Redirect("PropertyListing.aspx")
Else
Response.Redirect("AddProperty.aspx")
End If
Else
ShowError()
End If
Else
ShowError()
End IfEnd Sub
Private Function FindADUser(ByVal Properties As String()) As SearchResult
Dim Filter As String = String.Format("(&(objectClass=user)(objectCategory=person)(sAMAccountName=" + txtUserName.Text + "))")
Dim Entry As New DirectoryEntry(AppSettings("LdapPath"), txtUserName.Text, txtPassword.Text)
Dim Searcher As New DirectorySearcher(Entry, Filter, Properties)
Try
Return Searcher.FindOne()
Catch ex As Exception
Return Nothing
End Try
End FunctionThursday, August 17, 2006 10:02 AM -
User1354132231 posted
The problem is with your parameters to the IsInRole method. If you check the principal in 2.0, you should see a listing of the user's groups. In 1.1, you need to use the debugger and see the 'm_roles' private variable. In there, you should see a listing of the roles for the user. It is looking for that string specifically. For AD, this is going to look like "domain\username". It will never look like "xx\yy\something".
If you are checking one of the 'built-in' roles, you do not use the domain prefix, but you use the localized version of the word "builtin". So, checking for a Administrator on a US en server would be "BUILTIN\Administrator". However, since "BUILTIN" is not the same for every version of windows (it will be localized), you should use the WindowsBuiltinRoleEnumeration instead for these groups.
Finally, your FindADUser() function is a little fragile. First, you need to be calling Dispose() on the DirectoryEntry (in every case, everywhere, all the time on DirectoryEntry). Use the new "Using" statement in VB.NET or a Try/Finally statement to do this. Secondly, you are tossing away the error information. You might be failing for any number of reasons and you are ignoring it... I suspect when you deploy this code to a production server it will fail and you will not have any idea why.
Thursday, August 17, 2006 10:51 AM -
User1415440864 posted
Once again, thank you for helping.
How do I check the principal? I am using the 2.0. Sorry, I am still kind of a semi-newbie!
Thursday, August 17, 2006 11:29 AM -
User1415440864 posted
Also, that group that im trying to find is not a Builtin.Thursday, August 17, 2006 11:36 AM -
User1354132231 posted
Once again, thank you for helping.
How do I check the principal? I am using the 2.0. Sorry, I am still kind of a semi-newbie!
The Principal object in this case is HttpContext.Current.User. Just look at it in your debugger and inspect its members. It will either be a WindowsPrincipal or one of the others Generic or Forms, depending on how you are authenticating.Thursday, August 17, 2006 11:46 AM -
User1415440864 posted
I got it!! Thanks!
One more thing, can you give me an example of this?
"First, you need to be calling Dispose() on the DirectoryEntry (in every case, everywhere, all the time on DirectoryEntry). Use the new "Using" statement in VB.NET or a Try/Finally statement to do this."
Thursday, August 17, 2006 2:05 PM -
User1354132231 posted
I am not a VB.NET guy, so check out this post by Fritz. You can also search around and see how to use Try/Finally if you are only on .NET 1.1.
Thursday, August 17, 2006 6:37 PM -
User1415440864 posted
Ok thank you for your help!Friday, August 18, 2006 2:32 PM