How do I force ScriptManager to serve CDN scripts over SSL
Asked Answered
L

5

12

We have a site served on a web farm. The farm is behind an SSL Accellerator which handles the encryption. This means that our IIS servers see all incoming connections as http, even though users all connect to the site via https.

We are beginning to use the EnableCDN=true property of ScriptManager. While on our dev environments where there is no SSL Accellerator the references to the js files on the CDN are rendered with https, on the production environment they are rendered insecurely over http which is causing the js to be blocked with "Only secure content is displayed" errors.

Short of manually updating all the script references in scriptmanager or re-writing the HTML on the way out via a module, does anyone know of a way to force the scriptmanager to render its references via https?

EDIT:

After doing some reflector review, I don't believe this is possible. I've put the following hack into place, however this is obviously fragile as it involves accessing a private field. If anyone can see a better way I would love to hear it.

var secureConnectionField = ScriptManager.GetType().GetField("_isSecureConnection", BindingFlags.Instance | BindingFlags.NonPublic);
if (secureConnectionField != null)
    secureConnectionField.SetValue(ScriptManager, true);
Lavinia answered 22/11, 2011 at 4:28 Comment(3)
I haven't tried it for the case you describe, but there are a few places in HTML/JS where you can omit the protocol, and the browser will request the URL using the same protocol as for the containing page. For example, "//cdn.mydomain.com/myfile.js"Lifer
Thanks for the tip, but in this case I don't control the url rendered -- it is registered in the framework dlls. I don't believe there is a away to tell the script manager to omit the protocol when rendering the CDN references.Lavinia
ScriptManager is a Control, so you should be able to either build a Control Adapter that would override the path generation logic, or perhaps build a new Control that inherits from the original, and use tag mapping to dynamically replace it in your app.Lifer
T
1

If you use ASP.NET 4.0 or higher then one of the solution is to use ScriptResourceMapping feature of the ScriptManager control.

For example in global asax you can add the following code:

void Application_Start(object sender, EventArgs e) {

// map a simple name to a path

ScriptManager.ScriptResourceMapping.AddDefinition("jQuery", new ScriptResourceDefinition {

    Path = "~/scripts/jquery-1.3.2.min.js",

    DebugPath = "~/scripts/jquery-1.3.2.js",

    CdnPath = "http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.min.js",

    CdnDebugPath = "http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.js"

});

}

So, as you can see you can set CDN paths explicitly. Also, you can override the script mapping for standard Ajax files.

More information can be found in this article: http://weblogs.asp.net/infinitiesloop/archive/2009/11/23/asp-net-4-0-scriptmanager-improvements.aspx

Tamworth answered 11/11, 2012 at 16:1 Comment(0)
P
1

To handle a situation similar to yours, I configured the BundleCollection to use the CDN and two different version of the library for debug and production.

The result of these settings is that the non minified one will be used while debugging and the minified one from CDN will be used in production. The local minified one is ignored.

[...]  
bundles.UseCdn = true;
[...]
var jQueryBundle = new ScriptBundle("~/bundles/jquery");
jQueryBundle.CdnPath = "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js";
jQueryBundle.Include("~/scripts/jquery-1.9.1.js");
jQueryBundle.Include("~/scripts/jquery-1.9.1.min.js");
bundles.Add(jQueryBundle);

Note that I have not specified the protocol in the CdnPath, the client's browser will automatically use the current protocol the client is connected from, http or https.

The client's browser will receive the following tag in production:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

The developer's browser will receive the following tag:

<script src="/Scripts/jquery-1.9.1.js"></script>

Both will use the correct protocol on the browser.

Pandanus answered 9/4, 2013 at 21:44 Comment(0)
T
0

Normally your development and production servers will have different IP ranges. Ask the developement team to apply a "protocol switch" based on the IP addresses in the framework dlls.

Tun answered 14/12, 2011 at 22:22 Comment(1)
Thanks for the idea, but that doesn't really work for us, as the web servers still see the pages in http by design. We use the SSL accellerator to move the encryption load off of IIS. The scriptmanager is looking at what IIS is serving.Lavinia
T
0

Wether you are using @Razor it ASPX, I assume you have a Layout/MasterPage somewhere.

CDNs' true power lies in specifically having the script remotely hosted from some other source than your server's. Doing so prompts to be more likely that the user's browser has picked it up from a different location. CDNs perform best for core libraries, such as AngularJS or jQuery. The less popular the script you are importing is, the less recommended is to serve it through CDN.

I find it more suitable to hardcode-it on your Layout. If you use just the // instead specifying the protocol with http:// or https:// it should pick up the same protocol the page is being called.

<script type="text/javascript" src="//{yourCDNsource}"></script>

If you locally compress/minify a remote CDN it defeats the purpose. Better use NuGet or Bower for those.

Check Google CDNs

Tauro answered 16/4, 2014 at 15:50 Comment(0)
L
-1

Use this global.asax

void Application_Start(object sender, EventArgs e) {

// map a simple name to a path

ScriptManager.ScriptResourceMapping.AddDefinition("jQuery", new ScriptResourceDefinition {

    Path = "~/scripts/jquery-1.3.2.min.js",

    DebugPath = "~/scripts/jquery-1.3.2.js",

    CdnPath = "http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.min.js",

    CdnDebugPath = "http://ajax.microsoft.com/ajax/jQuery/jquery-1.3.2.js"

});

}
Laissezfaire answered 23/3, 2013 at 11:56 Comment(1)
You'd need to override every CDN path for every js file referenced by every dll. This seems like it would be impractical.Lavinia

© 2022 - 2024 — McMap. All rights reserved.