Microsoft KB Archive/910444

= SSL Termination and ASP.NET =

Article ID: 910444

Article Last Modified on 11/22/2007

-

APPLIES TO


 * Microsoft ASP.NET 2.0

-



SSL Termination and ASP.NET
''To customize this column to your needs, we want to invite you to submit your ideas about topics that interest you and issues that you want to see addressed in future Knowledge Base articles and Support Voice columns. You can submit your ideas and feedback using the Ask For It form. There's also a link to the form at the bottom of this column.''



Welcome to the ASP.NET Support Voice column! My name is Jerry Orman. I have been with Microsoft for over five years, and have spent most of my time focused on Web-related technologies such as Microsoft FrontPage and Microsoft SharePoint Products and Technologies. I've spent the last year working with Microsoft ASP.NET as a support engineer. This month, I'm going to talk about SSL Termination and ASP.NET. In particular, I want to focus on issues that result from a configuration of the server. We're going to take a look at SSL Termination and some side effects of this configuration on your application.

SSL Termination is a configuration in which the Web server running your code sends and receives traffic over HTTP, and there is a device between your Web server and your clients that encrypts and decrypts the data. In this configuration, the clients are sending and receiving HTTPS traffic. The SSL Termination configuration is similar to the following:

Client <— HTTPS —>SSL device <— HTTP —> Web server

Now let's go over two issues that come up in Microsoft ASP.NET 2.0 with this configuration, and some ways to work around the behavior.



Issue 1
When you hover over a menu item in the ASP.NET 2.0 Menu control, you get the following error message:

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

The application is supposed to be secure, you're using the SSL protocol, and you have not added any controls that are rendering an absolute path back to an HTTP address. What's up with this message?

Well, the problem is that the Menu control emits some JavaScript that uses an iFrame object to build the fly-out menu. You have to give the frame a starting URL. To avoid making an unnecessary round trip to the server for non-SSL scenarios, the script uses about:blank for the URL. However, the browser considers this an unsecure address, so you get the above error. For more information about this problem in terms of Microsoft Windows SharePoint Services, click the following article number to view the article in the Microsoft Knowledge Base:

837850 You receive a &quot;This page contains both secure and nonsecure items&quot; message when you click Explorer View in a document library in Windows SharePoint Services or in SharePoint Team Services from Microsoft

I explicitly mention non-SSL scenarios because, if the Web server was receiving the HTTPS traffic instead of the SSL device, the JavaScript that the Menu control emits would add a line of code to set the source of the iFrame object to an HTTPS address of a page on the server. This initiates another request, but prevents the error message. If you're deploying into this type of environment, you can force the addition of the JavaScript to prevent the error message by adding this code to the page that has the Menu control.  protected override void Render(HtmlTextWriter writer) {       Page.ClientScript.RegisterStartupScript(typeof(Page), &quot;MenuHttpsWorkaround&quot;,         Menu1.ClientID + &quot;_Data.iframeUrl='https://myserver/someblankpage.htm';&quot;, true); base.Render(writer); } Ideally, you would have the menu in a MasterPage class or a UserControl class, and could add this code just one time.

Issue 2
You may find that, when you have the requireSSL attribute of the   element set to true, the server responds with repeated redirects to the FormsAuthentication login page. This is caused by a change in the way the FormsAuthenticationModule method handles the requireSSL attribute. If you set the requireSSL attribute to true, the FormsAuthenticationModule method creates a cookie that has the secure attribute set. (This behavior is the same as in the .NET Framework 1.1.) When you use the secure attribute, the client will only pass the cookie to the server if the client is using SSL. This part is great, because the client is indeed using SSL. Let's assume you have a SecurePage.aspx page that anonymous users can't access. With the SSL protocol and the requireSSL attribute, you end up with the following traffic on an initial request to SecurePage.aspx:

—>Client makes a GET request for SecurePage.aspx.

<—Server responds with an HTTP 302 (Redirect) to the login page.

—>Client makes a GET request for Login.aspx.

<—Server responds with a 200 OK. The login page is rendered to client.

—>Client makes a POST request to Login.aspx.

<—Server responds with a 302 (Redirect) to SecurePage.aspx. Set Cookie header is sent with the secure attribute to the client.

—>Client makes a GET request to SecurePage.aspx. Cookie is passed because the client is using SSL.

<—Server responds with a 302 (Redirect) back to the login page.

You get the redirect in the last request because of a change in the FormsAuthenticationModule class. An additional check was added in ASP.NET 2.0 to determine whether the user is passing a secure cookie over a non-SSL request. ASP.NET 2.0 returns the FormsAuthenticationTicket class if the FormsAuthentication.RequireSSL property is set to false or if the Request.IsSecure attribute is set to true.
 * The FormsAuthentication.RequireSSL property is set to false if the requireSSL attribute is set to false in the configuration file.
 * The Request.IsSecure attribute is set to true if the Web server receives SSL traffic.

Since, in this scenario, the Web server is not receiving SSL traffic and the requireSSL attribute is set to true, both checks return false. As a result, the FormsAuthenticationTicket class is not returned and the cookie is removed from the Request.Cookies collection.

The request that the user is making is anonymous at this point because the server has not yet validated the user's credentials. As the request passes through the ASP.NET pipeline, the UrlAuthorizationModule class checks whether the user has access to the page. Since an anonymous user does not have access to a SecurePage.aspx page, the UrlAuthorizationModule class returns a 401 error message (&quot;Access Denied&quot;), which results in a redirect to the login page.

In order to avoid this behavior, you first have to remove the requireSSL attribute from the   tag in the configuration file. Then you have to programmatically set the secure attribute on the FormsAuthentication cookie. The following code does this for you, for both the FormsAuthentication cookie and the Session cookie. void Application_EndRequest(object sender, EventArgs e) { if (Response.Cookies.Count > 0) {         foreach (string s in Response.Cookies.AllKeys) {              if (s == FormsAuthentication.FormsCookieName || s.ToLower == &quot;asp.net_sessionid&quot;) {                   Response.Cookies[s].Secure = true; }         }     } }

