javascriptms-accessactivexadoactivexobject

Suppress ADO Security Warning in JavaScript/HTM Page


I have a fully functioning site stored on a network drive along with an Access Database which acts as the site's database. Due to lack of server side code, I am forced to use JavaScript to create an ADO ActiveX object to connect to the database. This works.

The problem I am having is that whenever the user opens the site an ADO Security warning appears asking if they trust the site. If they press 'Cancel' the error thrown is: Safety settings on this computer prohibit accessing a data source on another domain however the database is stored in the same network directory as the site... If they press 'OK' the site opens fine.

Is there any way of stopping this warning from appearing?


Solution

  • I know this is an old question, but I had the same issue, and it was maddening me that there were others also on SO with no answer - and I found out some info that should help some people, and I have a workaround:

    The issue with running this code from a web page is that it is bound by the security controls associated with that browser. The website user probably wouldn't get the same error if they used a different browser - and they are probably getting the error in IE, if I had to guess. In IE, there's a security control called "Access data source across domains", which is in the Miscellaneous section, if you go under Tools > Internet Options, Security tab, select the applicable zone for the site (probably Intranet, but this can be confirmed by looking on the IE status bar at the bottom while you are on the site, to see what zone is being applied), and select Custom Level. The problem comes in if the workstations are administered by GPO - Custom Level is greyed out. If not, you can find the setting, select Enable on the applicable client workstations that are accessing the site, and you're done.

    If it's administered by GPO, and you are an domain admin capable of making such changes:

    For the applicable OU in Active Directory Users & Computers for the client workstations where you want to make the change felt, right-click it and find the GPOs & edit. It is under: Local Computer Policy > Computer Configuration > Administrative Templates > Windows Components > Internet Explorer > Internet Control Panel > Security Page > Intranet Zone (probably) > first option: Access data sources across domains. Right-click it and select Edit. Select the Enabled radio button, then select Enabled in the dropdown.

    Select Apply and OK.

    If the client workstation does not get the update, either reboot, or do gpupdate /force on a command line to force a GPO update and reboot.

    If it's administered by GPO, and you are NOT a domain admin capable of making such changes:

    Go with a VBScript, instead. You can write a separate VBScript file with the connection, and you can even call it from JavaScript. Below is a script that has an ADO Connection that I pulled from https://gallery.technet.microsoft.com/scriptcenter/b160d928-fb9e-4c49-a194-f2e5a3e806ae as an example of how to format it. Granted, it is to AD and not Access, but the concept is the same:

    Option Explicit 
    
    Dim objGroup 
    
    'VERIFY A GROUP NAME WAS PASSED 
    If wscript.arguments.count <> 1 Then 
      wscript.echo "NO GROUP PASSED" 
      wscript.echo "Usage:  scriptName <groupSamAccountName>" 
      wscript.quit 
    End If 
    
    'BIND TO THE GROUP   
    Set objGroup = getGroup(wscript.Arguments(0)) 
    
    'ENUMERATE THE GROUPS MEMBERS 
    enumMembers objGroup, "" 
    
    Function getGroup(strGroupName) 
      Dim objConn, objRecSet, strQueryString, objRootDSE, strQueryFrom 
      Const adsOpenStatic = 3 
    
      Set objRootDSE = GetObject("LDAP://RootDSE") 
      strQueryFrom = "LDAP://" & objRootDSE.get("defaultNamingContext") 
    
      Set objConn = wscript.CreateObject("ADODB.Connection") 
      objConn.Provider = "ADsDSOObject" 
      objConn.Open 
    
      strQueryString = "SELECT AdsPath FROM '" & strQueryFrom & "' WHERE samAccountName = '" & strGroupName & "'" 
    
      Set objRecSet = wscript.CreateObject("ADODB.Recordset") 
    
      objRecSet.Open strQueryString, objConn, adsOpenStatic 
    
      If objRecSet.recordCount = 1 Then 
         Set getGroup = GetObject(objRecSet("AdsPath")) 
      Else 
         wscript.echo ucase(strGroupName) & " was not found in the domain. (" & objRootDSE.get("defaultNamingContext") & ")" 
         wscript.quit 
      End If 
    End Function 
    
    Sub enumMembers(byRef objGroup, strInheritedFrom) 
      Dim objMember 
    
      For Each objMember In objGroup.Members 
        If lcase(objMember.class) = "group" Then 
          enumMembers objMember, objMember.samAccountName 
        Else 
          If objMember.displayname <> "" Then 
             If strInheritedFrom = "" Then 
                 wscript.echo objMember.displayname 
             Else 
                 wscript.echo objMember.displayname & " (From NESTED GROUP:  " & strInheritedFrom & ")" 
             End If 
             Else 
               If strInheritedFrom = "" Then  
                   wscript.echo objMember.samAccountName 
               Else 
                   wscript.echo objMember.samAccountName & " (From NESTED GROUP:  " & strInheritedFrom & ")" 
               End If 
            End If 
         End If 
      Next 
    End Sub 
    

    In my case, it was when I placed this block into an HTA (which runs in a browser) and ran getGroup() with a particular group name from a button click event that I got my error. I wasn't even trying to get a group from a different domain! It didn't matter! So I had to pull this out into its own VBScript and run it on its own. I took the output I got and wrote it to a file (by storing the responses to a variable, with & vbCrLf after each result for a line break after each one, and sending it to code from here: http://www.computerperformance.co.uk/vbscript/vbscript_file_opentextfile.htm ). I won't include that code as it's even farther down the rabbit hole and off-topic. But you could write your output to a file and read it back in, if you had to, is my point. You might not have to. Once you extricate the code that is doing the data-grabbing into its own process, you'll probably be able to get around the error. But as long as it's tied to the browser security settings, it's going to appear and be a problem, though, so long as that setting stays disabled.