Link to home
Start Free TrialLog in
Avatar of andy44875
andy44875

asked on

ASP ADSI Authentication Issue - Will work fine for awhile then I am unable to authenticate unless I restart the application poll or IIS.

Has anyone ever experienced any problems authenticating with an ADSI application where after so long it stops responding. I can not track down what is causing the problem. I have a login page that uses the following code. This is running on a windows 2003 domain controller currently. If I put it on a windows 2000 member server I get this error way more often.

Dim oADsObject
Set oADsObject = GetObject(strADsPath)
Dim strADsNamespace
Dim oADsNamespace
strADsNamespace = left(strADsPath, instr(strADsPath, ":"))
set oADsNamespace = GetObject(strADsNamespace)
Set oADsObject = oADsNamespace.OpenDSObject(strADsPath, strUserName, strPassword, 1)

It authenticates fine, but after so long the login page stops working. If I restart the application pool the page starts to work again. I have a volume of about 500-700 users authenticated at any given time. Should I be authenticating a different way? I use this as a forms based authentication to a portal I built. I use all the error codes to redirect them if the password is expired etc. I thought about trying LDAP authentication, but I ran into problems where it would cache the password or something? If a user logged in and reset their password then logged out they could login with either password...

Any suggestions / help would greatly be appreciated.

Andy

Here is a post on ee that has the same process I am using however I get the issues above.
https://www.experts-exchange.com/questions/20920369/Active-Directory-login-using-ASP-NOT-ASP-Net.html#10612700
Avatar of slamhound
slamhound

Are you using your own login form or Windows authentication?

You can turn off "Allow Anonymous Users" in IIS and allow them to access the site using their standard Windows login. This is a bit more secure and easier than creating your own login page.

Are you cleaning up (destroying) the objects you've made once you've finished using them? You may just be hitting resource limits.
Avatar of andy44875

ASKER

I am using my own forms based authentication. I use forms based authentication because I check for many variables like if the password has expired etc. I also pass credientials to other applications to make a "single-signon" once they are in my portal. Below is a snapshot of what im doing.

<%
if (not strADsPath= "") then
      ' bind to the ADSI object and authenticate Username and password
      Dim oADsObject
            Set oADsObject = GetObject(strADsPath)
            Dim strADsNamespace
            Dim oADsNamespace
            strADsNamespace = left(strADsPath, instr(strADsPath, ":"))
            set oADsNamespace = GetObject(strADsNamespace)
       Set oADsObject = oADsNamespace.OpenDSObject(strADsPath, strUserName, strPassword, 1)

          domainstring = "NETWORK"
        groupstring = "nco-account-admin"

Set GroupObj = GetObject("WinNT://" & DomainString & "/" & GroupString)
For each UserObj in GroupObj.Members  
If UserObj.Name = Request.Form("username") then
networktools = "true"
else
end if

Next

          domainstring = "NETWORK"
        groupstring = "nco-reflection"

Set GroupObj = GetObject("WinNT://" & DomainString & "/" & GroupString)
For each UserObj in GroupObj.Members  
If UserObj.Name = Request.Form("username") then
reflection = "true"
else
end if

Next
   
                              
' we're only  bound if err.number = 0
Select Case Err.number

                              Case 0
                              session("udistrict") = trim(RS("udistrict"))
                              session("uall") = trim(RS("uall"))
                              session("uemis") = trim(RS("uemis"))
                              session("ufiscal") = trim(RS("ufiscal"))
                              session("uinfohio") = trim(RS("uinfohio"))
                              session("usis") = trim(RS("usis"))
                              session("utac") = trim(RS("utac"))
                              session("uprodev") = trim(RS("uprodev"))
                              session("distid") = trim(RS("description"))
                              Session("title") = title
                              Session("dirn") = dirn
                              session("email") = email
                              session("dbuser") = username
                              session("username") = strUsername
                              session("password") = strPassword
                              session("reflection") = reflection
                              session("networktools") = networktools
                              session("nraccess") = trim(RS("nraccess"))
                              session("nameuser") = nameuser
                              session("id") = id
                              session("login") = "True"
                              call success()
                                    
                              Case -80070775
                              errFlag = true
                            call lockedaccount()
                              
                              Case -2147943726, -2147023570, -2147024810, -2147023677, -2147022694
                                    errFlag = true
                                    call invalidaccount()
                              Case -2147023565
                                    errFlag = true
                                    call disabledaccount()
                              Case -2147022987
                                    errFlag = true
                                    call lockedaccount()
                              Case -2147022989, -2147023541, -2147023688
                                    errFlag = true
                                    call passwordexpired()
                              Case else
                                    errFlag = true
                                    response.write "If you get this message please report it to support(support at blah):. " & Err.number &                        " " & Err.Description
                        end select
                        err.clear
                        set oADsObject = nothing

end if
end if
Put these at the end of your code to clean up.
Set oADsObject = Nothing
Set oADsNamespace  = Nothing
Set GroupObj = Nothing

At the same time, you may want to use close statements to cleanup also. eg: oADsObject.close  (This may only be for LDAP but give it a try)

Slamhound,
I have addded these commands per your suggestion.



Does anyone know if there is a way to monitor the app pool for the amount of sessions that are active? I know I could use the windows preformance monitor, but is there any way to gather more detailed information.

Andy
Slamhound,

Do you think doing authentication via LDAP is more stable?

I was using LDAP in the mannor below, but noticed some weird things that would occur. If a user reset their password they could get in with their old password and new password. I am wondering if this is just due to the fact a cache stays in effect in active directory for a period of time? It just didn't seem that secure so before troubleshooting I got away from using that method and started using ADSI.


Set dso = GetObject("LDAP:")
Set domain = dso.OpenDSObject("LDAP://Network", strUsername, _
                              strPassword, _
                              ADS_SECURE_AUTHENTICATION)

'Cleanup:
    If (Err.Number <> 0 ) Then
        MsgBox("An error has occurred. " & Err.Number)
    End If
    Set dso = Nothing
    Set domain = Nothing

Andy
I've got no comparison info for this one as I've only used LDAP so I can't tell you what's better. But even in the above sample code it would be good to close the dso when you've finished with it. Officially setting it to Nothing means that you blow away all the old stuff but I'm wondering if the aparent caching issues are caused because there's still junk in the old object.

Having said all that, I think I must have abandoned the above code I was talking about. When I went back to look I found that I was using this code to grab the username from their IIS username (but should work fine if they've entered their username in a form too).

Function GetADUsername(Uname)

            ' trying to get the name of the user from sAMAccountName
            Set objRoot = GetObject("LDAP://RootDSE")
            sDomainPath = objRoot.Get("DefaultNamingContext")
            Set con = Server.CreateObject("ADODB.Connection")
            con.provider = "ADsDSOObject"
            con.open "Active Directory Provider"
            Set Com = Server.CreateObject("ADODB.Command")
            Set Com.ActiveConnection = con
            Set rstemp = Server.CreateObject("ADODB.Recordset")
            Com.CommandText = "select name, sAMAccountname from 'LDAP://" & m_cOrganUnit & "," & sDomainPath & "' WHERE sAMAccountname='" & Uname & "'"
            Set rstemp = Com.Execute
            if not rstemp.EOF then
                  GetADUsername = rstemp.fields("name")
            end if
end function
Slamhound,

This is just going to check if the username exists, but not check that the password is correct right? I need check authentication at this point because I am also checking to see if the account has an expired password or not and redirecting them to a change password utility.

Let me know,

Andy
ASKER CERTIFIED SOLUTION
Avatar of slamhound
slamhound

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial