Nonsecure items message using Menu control over SSL

If you're using the new menu control that ships with ASP.NET 2.0 and SSL Termination/Acceleration, you will run into this issue. The behavior the end users will see is a warning in the browser stating something similar to:

This page contains both secure and nonsecure items.
Do you want to display the nonsecure items?

The user is browsing using HTTPS, so where is the non-secure item?

This is actually caused by the way the menu control was implemented. When you hover over a menu item, the popup menu is created using frames. For performance reasons, if the URL that the server receives is HTTP, the script that builds the popup menu uses about:blank as the default page. This is done to increase performance since the browser won't have to make another request to the web server just to temporarily populate a frame. If the server receives the URL as HTTPS, the script actually makes a request back to the server to an HTTPS address to populate the frame.

So...if you use SSL termination or SSL acceleration you end up with the following network architecture:

Client --> SSL --> Termination/Acceleration device --> HTTP --> Web Server

Even though the client is using SSL, the web server is getting HTTP traffic. As a result, the menu control does not inject the script to populate the popup using an SSL address. When the client hovers over the menu item, the popup tries to go to about:blank. This is considered a protocol transfer in IE which causes the warning to display.

That was a bit long winded, but it's good to know why your getting an message before trying to change it :)

The easiest way to get the warning to go away is to manually inject the line of script that forces the client to populate the popup using an SSL address. This would look like:

<script runat="server">
protected override void Render(HtmlTextWriter writer)
Page.ClientScript.RegisterStartupScript(typeof(Page), "MenuHttpsWorkaround", Menu1.ClientID + "_Data.iframeUrl='https://myserver/someblankpage.htm';", true);