in

simplusoft.net

another .NET open source community

iulia

Cross domain calls by means of iframe – IE Browser restrictions and solutions

Cross domain calls by means of iframe – IE Browser restrictions and solutions


All modern web browsers impose a security restriction on network connections. This restriction prevents a script or application from making a connection to any web server other than the one the web page originally came from (Internet Explorer will allow cross-domain requests if the option has been enabled in the preferences). If both your web application and the XML data that application uses come directly from the same server, then you do not run into this restriction.
But, if you start a web application App1 which is on the domain testdomain1 and call from it using iframe another application App2 which is on different domain testdomain2 and you are using AjaxControlToolkit you will receive a security error “Access denied.”

if
http://testdomain1/App2
calls using iframe
http://testdomain2/App2  =>  you will receive Access denied

There are several options to make work the calls around cross-domain browser restrictions:

1. Change IE Security Settings

If you are using Internet Explorer you can enable “Access data sources across domains” for your Trusted zones after you add the http://testdomain2 into Trusted Zones like in the image below:

And also enable “Navigate sub-frames across different domains” like in the image:
 

The problem in this case is that if the client is in a domain controller and this overrides the security IE policy rules, your settings will be allays overridden.
The programmer can have access to the client browser settings and can set the above options in the following ways:
• Using the below script which works only if IE has security settings on low (this will set both on Local Intranet and Internet)
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<head>
    <title>Untitled Page</title>
</head>
    <script language=vbscript>
        sub SetInRegistry()
            Set WshShell = CreateObject("WScript.Shell")
            KVLocalIntranet = "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1\1406"
            KVInternet = "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\1406"
            dwValue = "0"

            WshShell.RegWrite KVLocalIntranet, dwValue, "REG_DWORD"
            WshShell.RegWrite KVInternet, dwValue, "REG_DWORD"
        end sub
    </script>
   
    <body>
        <form name="Form1" method="post" id="Form1" runat=server>
            <input type=button value="Set in registry" onclick="SetInRegistry"/>
        </form>
    </body>
</html>
• Using a .hta file wich will work always no matter what security settings IE has
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
</head>
    <script language=vbscript>
        sub test()
            const HKEY_LOCAL_USER = &H80000001
            Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
            strKeyPathLocalIntranet = "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1"
            strKeyPathInternet = "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" 

            strValueName = "1406"
            dwValue = 0
            oReg.SetDWORDValue HKEY_LOCAL_USER, strKeyPathLocalIntranet, strValueName, dwValue
            oReg.SetDWORDValue HKEY_LOCAL_USER, strKeyPathInternet, strValueName, dwValue
        end sub
    </script>
 
 <body>
  <form name="Form1" method="post" id="Form1" runat=server>
      <input type=button onclick="test()">
  </form>
 </body>
</html>

Adrian Matei  has created the above scripts for modifying the IE security settings.

2.Install a proxy on your web server

Instead of making your XMLHttpRequest calls directly to the web service, you make your calls to your web server proxy. I didn’t try this solution.

3.The two domains involved in calls has to be one subdomain of the another

So, in our example we have to put App1 on the domain a.testdomain.com, and the second application App2 on the domain b.testdomain.com where b.testdomain.com is, in fact, a subdomain of the a.testdomain.com.But this is not enough. In order the calls to work, you have put document.domain=" testdomain.net" in the script section of both pages.
For this solution, you can find related link:
 http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_23022516.html

In order to implement this solution you have to be able to create sub domains, which is not always very simple for a developer.


4. Trus relations between domains

One network administrator talk about the possibility to create trust between the 2 domains, and this has to normally enough, but I have to recognize I didn’t test this solution.

5. Microsoft recommendation

Microsoft has a recommendation for this problem at http://support.microsoft.com/kb/936993 . Here are exposed 2 solutions; either “Make sure that the Web page that contains the <iframe> element and the Web page to which the <iframe> element points are in the same domain” either modify the jacascript pages from AJAX Extension package. I try to implement the second recomandation but for the last version of AjaxToolkit I found that they are already implemented, and still doesn’t work.


6. Workable solution -  Point only the core framework to a file

This is the solution which I have implemented and works. It’s not to have all your script references path-based as Microsoft recommends above, which means to point your script manager from the App2 to the local files using script path property.
The workable solution has the following steps:
 

  • in the App2 create a subfolder “Scripts” and copy here the all folder “System.Web.Extensions” (which you will find most probably in “..\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\MicrosoftAjaxLibrary\System.Web.Extensions”)
  • The second step is to patch the files. You’ll need to patch the debug and release versions.

         The debug version is MicrosoftAjax.debug.js. Look for the following code:

        switch(Sys.Browser.agent) {
       case Sys.Browser.InternetExplorer:
         then replace everything between that and "case Sys.Browser.Safari:" with the following code:

      Sys.UI.DomElement.getLocation = function(element) {
       if (element.self || element.nodeType === 9) return new Sys.UI.Point(0,0);
     var clientRect = element.getBoundingClientRect();
     if (!clientRect) {
        return new Sys.UI.Point(0,0);
     }
      var ownerDocument = element.document.documentElement;
     var offsetX = clientRect.left - 2 + ownerDocument.scrollLeft,
         offsetY = clientRect.top - 2 + ownerDocument.scrollTop;
   
    try {
        var f = element.ownerDocument.parentWindow.frameElement || null;
        if (f) {
            var offset = 2 - (f.frameBorder || 1) * 2;
            offsetX += offset;
            offsetY += offset;
        }
    }
    catch(ex) {
    }   
   
    return new Sys.UI.Point(offsetX, offsetY);
}
break;
For the release version (MicrosoftAjax.js), the process is pretty much the same except that the file is a little more difficult to manipulate. Look for "switch(Sys.Browser.agent){case Sys.Browser.InternetExplorer:" and replace everything between that and "case Sys.Browser.Safari:" with the following:

Sys.UI.DomElement.getLocation=function(a){if(a.self||a.nodeType===9)return new Sys.UI.Point(0,0);var b=a.getBoundingClientRect();if(!b)return new Sys.UI.Point(0,0);var c=a.document.documentElement,d=b.left-2+c.scrollLeft,e=b.top-2+c.scrollTop;try{var g=a.ownerDocument.parentWindow.frameElement||null;if(g){var f=2-(g.frameBorder||1)*2;d+=f;e+=f}}catch(h){}return new Sys.UI.Point(d,e)};break;

(no line breaks)

The site should now work without the exceptions.


  • Point only the core framework to a file and leave the others to use web resources as usual. This makes things easier when using other resource-based libraries such as the toolkit. This is easily done by adding the following script reference to your script manager:
    <asp:ScriptReference
        Name="MicrosoftAjax.js" ScriptMode="Auto"
        Path="~/ Scripts/System.Web.Extensions/1.0.61025.0/MicrosoftAjax.js"/>

Don't set a ScriptPath on the script manager if you choose to use this script reference. Once you’ve done that, you can check that the applications work. This fix implies that you stop using the resource-based scripts and use the static file versions instead.

I have to notice that I didn’t find this security problem when I used Mozilla Firefox, but there is still good news: it seams that this is fixed in ASP.NET 3.5.

Other related links:
http://msdn2.microsoft.com/en-us/library/ms533028(VS.85).aspx

http://support.microsoft.com/kb/936993

http://blogs.msdn.com/delay/archive/2007/02/05/safely-avoiding-the-access-denied-dialog-how-to-work-around-the-access-denied-cross-domain-iframe-issue-in-the-ajax-control-toolkit.aspx

http://www.thecodecave.com/article213


 

Comments

No Comments
Simplusoft.net is a non-profit community dedicated to all .NET developers
Powered by Community Server (Non-Commercial Edition), by Telligent Systems