Programmer to ProgrammerTM  
Wrox Press Ltd  
   
  Search ASPToday Living Book ASPToday Living Book
Index Full Text
 
ASPToday Home
 
 
Bullet HOME
Today TODAY
Index INDEX
Full-text search SEARCH
Reference REFERENCE
Feedback FEEDBACK
Advertise with us ADVERTISE
Subscribe SUBSCRIBE
Bullet LOG IN
                         
 
 
  Register for FREE Daily Updates:  
  Email:  
 
  The ASPToday Article
March 7, 2001
      Previous article -
March 6, 2001
   
 
   
   
   
Using ADSI and Groups on Windows 2000   Christopher Schmidt  
by Christopher Schmidt
 
CATEGORY:  DNA 2000  
ARTICLE TYPE: Overview Reader Comments
   
    ABSTRACT  
 
Article Rating
 
   Useful
  
   Innovative
  
   Informative
  
 12 responses

In his last article, Chris Schmidt talked about Using ADSI, NT Groups and IIS Authentication. This article focused primarily on Windows NT and IIS 4. Since then, he has received several questions about errors using GetObject and about how to apply his previous article to Windows 2000 and IIS 5. This article answers these questions and explains the differences between Windows NT and 2000 using this approach for authentication and user management.

   
                   
    Article Discussion   Rate this article   Related Links   Index Entries  
   
 
    ARTICLE

In my last article for ASPToday you read about Using ADSI, NT Groups and IIS Authentication. This article focused primarily on Windows NT and IIS 4. Since then, I have had several questions about errors using GetObject and about how to apply my previous article to Windows 2000 and IIS 5. This article answers these questions and explains the differences between Windows NT and 2000 using this approach for authentication and user management.

Questions asked by Readers

The most popular question asked is

"I get an error when calling this code - Set objUser = GetObject("WinNT://" & strUserID) Why?"

Usually the solution for this problem is installing ADSI 2.5. The first important difference between using ADSI on Windows NT and Windows 2000 is that ADSI is not installed when Windows NT is loaded. ADSI had to be downloaded from the Microsoft website and installed on Windows NT, whereas with Windows 2000, ADSI 2.6 is already installed with the Operating Systems.

If ADSI was installed on a Windows NT box, the other problem was the ADSI path passed to GetObject. When using ADSI, the path is referred to as ADsPath. Using ADSI on Windows NT or 2000, you must understand ADsPath. Just as a file has a fully qualified path in the file system, objects like a user or a group have a string representation of their exact path in the directory hierarchy, hence ADsPath.

The ADsPath syntax is:

ADSI Provider://Namespace

The provider name is the initial elements of the ADsPath. The provider name is the ProgID (Programmatic Identifier) of the ADSI Provider. The ProgID section of the syntax is case sensitive. The Windows NT directory service ProgID is WinNT. Other ProgIDs are LDAP for Lightweight Directory Access Protocol and NDS for Novell Directory Service. A complete list of ProgIDs and Provider Names (along with a lot more information) can be found on the Microsoft website at:

http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/adsi/adsistartpage_7wrp.htm&WROXEMPTOKEN=1146165ZO4ed82MHJbFg6oYYgG.

The :// is just a separator between the Provider and Namespace in the ADsPath.

The Namespace refers to a directory service that has a specific syntax for access. The namespace is a string in that syntax. For example, if the ProgID is WinNT, then a valid namespace would be MyServer/MyUserName. Each ADSI provider has a different syntax for accessing its directory service.

Here are some examples of ADsPaths:

WinNT://MyDomain/SomeUserName
WinNT://MyServer/MyUserName
LDAP://MyServer:Port/o=OrgName

Code and Read at the same time

If you want to setup the project and code as you read the article, please follow these steps:

Setting up User Groups and IIS Authentication

There are many differences between setting up users, groups, directory security and IIS authentication on Windows NT and 2000. This section explains how to create users to IIS authentication on Windows 2000. Please see my previous article for instructions on how to do this in Windows NT.

Creating a user

image1

For the sample code, you need at least two users. The two users I will be using are cschmidt and the NewUser, which I just created.

Creating a Group and Adding a User

image2

The sample code below uses two groups: UserGroup and AdminGroup. The UserGroup has one member: NewUser while the AdminGroup has Administrator as a member. During the development phase, you will want to be a member of both groups so Visual Interdev can access and update the website.

Configuring the NTFS permissions

Now we need to configure the NTFS permissions for our ADSIProject. Bear in mind that for this to work, your hard drive needs to be formatted to NTFS, not FAT32. This will be an obvious point to most of you, but one that some may overlook, which is why I have included it. Follow the steps below:

image3

What did you just do? Great Question. You changed the Access Control Entries (ACEs) for the Access Control Lists (ACLs) on each directory to only allow the Groups to access the proper resources. Note: ACLs are only used on NTFS drives. If your drive is FAT, you must convert it to NTFS in order to take advantage of Groups restricting access in the File System.

IIS Authentication

Next, setting up the IIS authentication:

image4

Basic Authentication works the same as IIS 4.0. For your Netscape users, their usernames and passwords are sent in clear text, so you have to add SSL. For your IE users, Internet Explorer authenticates using Integrated Windows Authentication. This is similar to NTLM in IIS 4.0. You do not need SSL for your IE. Also note that you remove Anonymous Authentication because in this example, we do not want anonymous logins to the web site.

Now it's time to start coding.

Start Coding

Let's start with index.asp. When the user attempts to access this page, IIS takes over and the user is challenged for his username and password. Once the user successfully logs in, the login.asp code is executed. The following is the code for the login.asp:

If (Session("isValidLogin") <> True) Then 

Dim userObj 
Dim userGroupsObj 

Session("isValidLogin") = False 

If (InStr(1, Request.ServerVariables("AUTH_USER"), "\") > 0) Then 
   ' The Domain was passed in with the user name
   Session("AUTH_USER") =
         Replace(Request.ServerVariables("AUTH_USER"), "\", "/")
   Session("SERVER_NAME") = Left(Session("AUTH_USER"), 10) 
   strADsPath = "WinNT://" & Session("AUTH_USER") 
Else 
   ' This is a local user
   Session("AUTH_USER") = Request.ServerVariables("AUTH_USER")
   Session("SERVER_NAME") = "yosemite" 'Replace with your server
   strADsPath = 
      "WinNT://" & Session("SERVER_NAME") & "/" & Session("AUTH_USER") End If

Set userObj = GetObject(strADsPath)

Session("FullName") = userObj.FullName 
Set userGroupsObj = userObj.Groups() 

For Each Group In userGroupsObj 
   Select case Group.Name 
      case "UserGroup": 
         Session("isUserGroup") = True 
         Session("isValidLogin") = True 
            case "AdminGroup": 
         Session("isAdminGroup") = True 
         Session("isValidLogin") = True 
      End Select 
   Next 

   Set userObj = Nothing 
   Set userGroupsObj = Nothing 

End If 

If (Session("isValidLogin") = False) Then 
Response.Redirect("invalidlogin.asp") 
End If

First login.asp checks to see if the isValidLogin session variable is not set to true. If it does not equal true, then this is the first time login.asp has been called in this session.

Since the user is authenticated, the script retrieves the user name and sets up the ADs path to get the user info. Calling the GetObject function in this case returns the ADSI user object (IADsUser).

Next, the Groups() method is called, which returns the collection of groups (IADsGroups). Since all ADSI objects require the IADs interface, we have access to the name of each group in the collection. Now, we can loop through the collection, setting our session variables appropriately. The user is now logged on.

Just in case you were wondering, the solution presented is Netscape 4.51 and IE 4/5 compliant. For Netscape and IE, users can login using this syntax: Domain\UserName. IE 4.0 and 5.0 can be configured to automatically log in on Intranet zones. Although the user never sees an authentication dialog box, IE is passing the authentication information. To force the authentication dialog box to popup, only allow Basic Authentication for IIS. When doing so, users must login with Domain\UserName for the user name. This way the proper syntax can be retrieved when calling Request.ServerVariables("AUTH_USER"). If the user does not login this way, only the username is passed to the AUTH_USER server variables, thus the Groups() method fails in the UserGroups() function. In order to get around this error on a web site where users are local to the web server and belong to various domains, you use the following code (already found in login.asp):

If (InStr(1, Request.ServerVariables("AUTH_USER"), "\") > 0) Then 
   ' The Domain was passed in with the user name
   Session("AUTH_USER") "/") =
         Replace(Request.ServerVariables("AUTH_USER"), "\", "/")
   Session("SERVER_NAME") = Left(Session("AUTH_USER"), 10) 
   strADsPath = "WinNT://" & Session("AUTH_USER") 
Else 
   ' This is a local user
   Session("AUTH_USER") = Request.ServerVariables("AUTH_USER")
   Session("SERVER_NAME") = "yosemite" 'Replace with your server
   strADsPath = 
      "WinNT://" & Session("SERVER_NAME") & "/" & Session("AUTH_USER") End If

This code checks to see if a backslash exists in the AUTH_USER server variable. If it does then the domain was included in the AUTH_USER server variable. This means we just need to replace the back slash with a forward slash. We can also extract the server out of the AUTH_USER variable for later use. If a backslash does not exist in the AUTH_USER variable, then the user is a local user so the web server and the ADsPath is created by concatenating WinNT:// with SERVER_NAME and AUTH_USER.

Now, since login.asp assigns the full name of the user according to the SAM to a session variable and sets up the session variables isUserGroup and isAdminGroup, we can manipulate a users experience on the website.

Here is one way to manipulate the user experience. This is code from index.asp.

  <%If (Session("isUserGroup")) Then %>
      <A href="User/FormA.asp">Form A</A>
  <%End If%>

Here is what the user NewUser would see after index.asp is called.

image5

Remember to go into ISM, then get up properties for ADSIProject, then go to the Documents tab and add Index.asp as a default document if you wish to reach it using equivalent to the above URL.

Why did I choose to use Session Variable? Why not use ADSI to query each time the user has to access a restricted area? The answer: Performance. Using ADSI to query for the user info each time hurts performance, especially on large domains. The disadvantage of using the session variables is that the session times out.

How do you handle this? Since the Authentication is still valid, we just need to call login.asp to recreate the session variables. Login.asp checks to see if the session variable isValidLogin is not equal to true. If that's the case then the session variables need to be recreated.

In order to recreate the session variable when the session times out, just add this code to the beginning of each ASP file.

<!-- #include Virtual="/ADSIProject/login.asp" -->

Web Site User Management

The best part of ADSI is being able to create a simple web interface for user management. Once this site is in production mode, your support division can take over requests from users. Your support division can add or remove users and filter problems to the developers and/or system administrators as needed so your time is freed up to start the next app on your to do list.

In the case of small IT teams that do not have a support division, you could train secretaries or administrative assistants to add/remove users. Most of the companies that my colleagues and I have worked for are starting to take advantage of these secretaries and administrative assistants to help the IT Staff, who, as many companies are hoping (in the long run, after testing the waters), can be trained as full IT Staff.

Back to ADSI - let's display the users that belong to the UserGroup group. This code is located in the usermngt.asp file.

strPath = "WinNT://" & strServer & "/UserGroup" Set objGroup = GetObject(strPath) 
strHTML = "<SELECT size=10 multiple id=UserGroup name=UserGroup>" 

For Each objUserInfo In objGroup.Members 
   strHTML = strHTML & "" & Mid(objUserInfo.Parent, 9) & "/" & objUserInfo.Name & "" 
Next 

strHTML = strHTML & </SELECT>
Set objGroup = Nothing 

Response.Write(strHTML)

This is fairly simple. First, call the GetObject Function with an ADs path to the local Group. An IADsGroup object is returned which contains a collection of members (a member can be a user or another group). Then, loop though that collection, displaying the members.

To add a user, we need to display a list of users to choose from. Take a look at AddUser.asp:

strPath = "WinNT://" & strServer & "/" & strGroup 
strDomain = Request.Form("Domain")
Set objGroup = GetObject(strPath)

For Each Item In Request.Form(Request.Form("Domain"))Request.Form(strDomain) 
   If (NOT(objGroup.IsMember("WinNT://" & strDomain & "/" & Item))) Then 
      objGroup.Add "WinNT://" & strDomain & "/" & Item 
   End If 
Next 
Set objGroup = Nothing

This code is very similar to displaying users of a Group except we change the AdsPath to a domain path. In this code, I use a filter to only retrieve the users. You could also retrieve the groups in the Domain, after which you could also add groups to the group.

Here is the code to actually add a user to the group:

strPath = "WinNT://" & strServer & "/" & strGroup 
Set objGroup = GetObject(strPath) 
For Each Item In Request.Form(strGroup) 
   objGroup.Remove "WinNT://" & Item 
Next 
Set objGroup = Nothing

Once you have all of your user management code working using VBScript, it is important to move your code into a COM+ object. Since your code is already in VBScript, it's easiest to write your COM+ object as an ActiveX DLL written in Visual Basic. The reason you want to do this is because a COM+ object can be executed under the administrator for the domain. The AdminGroup can then be given access to the COM+ object. If you do not do this, then anyone assigned to the user management of the web app must also be an administrator for the domain.

Other Functions for ADSI

Other great things that you could do:

Conclusion

Using ADSI, Windows 2000, SQL Server 2000 and IIS 5 will help with administration of your web apps as well as how the web app is presented to users with different permissions.

 
 
   
  RATE THIS ARTICLE
  Please rate this article (1-5). Was this article...
 
 
Useful? No Yes, Very
 
Innovative? No Yes, Very
 
Informative? No Yes, Very
 
Brief Reader Comments?
Your Name:
(Optional)
 
  USEFUL LINKS
  Related Tasks:
 
 
   
  Related ASPToday Articles
   
  • Using ADSI, NT Groups and IIS Authentication (April 17, 2000)
  • Real World ADSI (November 9, 1999)
  • Exploring the NT Directory Services (August 6, 1999)
  • An Introduction to ADSI (March 10, 1999)
  •  
           
     
     
     
           
      Search the ASPToday Living Book   ASPToday Living Book
     
      Index Full Text Advanced 
     
     
           
      Index Entries in this Article
     
  • ACEs
  •  
  • ACLs
  •  
  • ADSI
  •  
  • COM+ components
  •  
  • configuring
  •  
  • GetObject function
  •  
  • Groups method
  •  
  • groups, adding users
  •  
  • groups, creating
  •  
  • IADsUser object
  •  
  • IIS 4.0
  •  
  • IIS 5
  •  
  • IIS Authentication
  •  
  • installing
  •  
  • integrated applications
  •  
  • Integrated Windows Authentication
  •  
  • ISM
  •  
  • NT
  •  
  • NTFS permissions
  •  
  • NTLM
  •  
  • problems with
  •  
  • session variables
  •  
  • user authentication
  •  
  • users, creating
  •  
  • web site administration
  •  
  • Windows 2000
  •  
     
     
    HOME | TODAY | INDEX | SEARCH | REFERENCE | FEEDBACK | ADVERTISE | SUBSCRIBE
    .NET Framework Components Data Access DNA 2000 E-commerce Performance
    Security Admin Site Design Scripting XML/Data Transfer Other Technologies

     
    ASPToday is brought to you by Wrox Press (http://www.wrox.com/). Please see our terms and conditions and privacy policy.
    ASPToday is optimised for Microsoft Internet Explorer 5 browsers.
    Please report any website problems to [email protected]. Copyright © 2001 Wrox Press. All Rights Reserved.