Old bug finally squashed

A year-and-a-half or so ago, I was working on an ASP.NET project that used SSL and forms authentication. No big deal, a pretty conventional setup, I'd expect. Anonymous users requesting any of the site's ASPX pages were redirected automatically to a secure login page, so usernames and passwords went over encrypted SSL to the server. Works great, the site's been live and working in the field for over a year. But there was one niggle that caused a few headaches during development. Basically, every time you opened the web project, VS.NET would complain that it was being redirected to a secure connection, and refuse to open it. I found a workaround at the time, which was basically to rename the app's web.config file immediately before opening the solution (disabling the forms authentication redirection), and then name it back after the project had opened successfully. Not a big thing, but annoying - to be honest, I'd forgotten all about it. Still, left a little bit of an 'unfinished business' taste in the back of the mouth.

Then, this week, we started a new project based off some of the code for that old application, and the bug is back, annoying as ever. So, I decided it was time to fix it once and for all. This time, not unsatisfying hacky workarounds that you had to fiddle with each time you started the project - I found a much better hacky workaround that you only have to do once and it fixes it once and for all. Since I can't imagine I'm the only person in the world developing a site with a secure forms-authentication login page and someone else out there might benefit from this, I thought I'd share the adventure, and the fix, on here. If you're looking at this page after searching Google for 'Visual Studio .NET redirected to secure connection can't open web project', then you've hopefully found what you're looking for.

So, how did we solve this one? Well, I decided to take a look in my web server logs to find out exactly what VS.NET was requesting from the server that was causing it to get redirected to a secure connection in the first place, and found a couple of surprising requests. Here's what the log entries looked like:

15:03:21 127.0.0.1 GET /SD2/Admin/vs138455456329692582_tmp.htm 200
15:03:21 127.0.0.1 GET /_vti_inf.html 200
15:03:21 127.0.0.1 POST /SD2/Admin/_vti_bin/shtml.dll/_vti_rpc 405
15:03:21 127.0.0.1 GET /_vti_inf.html 200
15:03:21 127.0.0.1 POST /_vti_bin/shtml.dll 200
15:03:21 127.0.0.1 POST /_vti_bin/shtml.dll 200
15:03:31 127.0.0.1 GET /SD2/Admin/get_aspx_ver.aspx 302
15:03:31 127.0.0.1 GET /SD2/Admin/Secure/UserLogin/Login.aspx 403
15:03:31 127.0.0.1 GET /SD2/get_aspx_ver.aspx 404

So the first of these looks like VS.NET verifying that web requests to this path end up in the directory it thinks they do (it's creating a temprary file in the directory, then trying to request it). This test is passing fine. Then it's looking at those nasty frontpage server extension files that it leaves all over the place, and firing a few POST rquests in to DLLs - who knows what it's up to, but it's none of our concern. Then we see the line that must be causing the whole thing: it's trying to GET get_aspx_ver.aspx. This is resulting in a 302 redirect response. That'll be where the problem's coming from.

Why? Well, before we get to that, it's worth noting that it's surprising that it gets a 302 at all, because no such page exists on my site. If I request that page myself, I get a 404, not a redirect to the login page. So, VS.NET must be creating it first, right before it requests it - just like it did that _tmp.htm page. This looks like a slightly hacky attempt by VS.NET to verify that ASP.NET 1.1 is running on the server: stick a known ASPX page into the directory, request it (forcing it to execute in the context of the ASP.NET application), resulting in it emitting some sort of output that VS.NET can use to determine the version of ASP.NET that's executing it. Dirty, but I guess it works. Sometimes. Of course, it doesn't work on this occasion, because all requests for ASPX pages are handled by the ASP.NET pipeline, and one of the things on that pipeline is my forms authentication configuration. Since VS.NET is considered an 'anonymous client', forms auth decides that it needs to go and log in. VS.NET then tries to do as it's told, and request the login page, and gets a 403 response, telling it it needs to use a secure connection. At that point, I'm guessing we get the error message.

So, at this point, we know why VS.NET is complaining - and therefore, we know enough to create a pretty good workaround. All we need to do is tell the authorisation system that anonymous clients are allowed to request get_aspx_ver.aspx. Add this to web.config:

<location path="get_aspx_ver.aspx">
  <system.web>
    <authorization>
      <allow users="*"/>
    </authorization>
  </system.web>
</location>

Case solved - the annoying bug is finally squashed. Maybe not ideal, polluting the web.config with extraneous authorisation hacks, but to be fair, that's only the development machine's config file. I can live with it. In a week of other development frustrations, finally beating an old niggling bug like that was just what I needed.

Print | posted on Wednesday, February 16, 2005 3:47 PM

Comments on this post

# re: Old bug finally squashed

Requesting Gravatar...
Thanks. Nice!

I just ran into that problem a couple days ago.
My situation involves a user control "ForceSSL" that I put on pages which I want to require access via SSL. My workaround was to add a configuration setting and check it:
<appSettings>
<add key="ForceSSL" value="True" />
</appSettings>
When I set that to False, it just redirects to the Login page using HTTP, instead of requiring HTTPS. It works OK on a dev machine, but wouldn't be appropriate for a live site.

I'll still keep the ForceSSL setting, in case I want to use this code in less-secure sites that won't require SSL.

Your solution is more robust, and it works just great.

Left by BillT on Mar 22, 2005 6:44 PM

Your comment:

 (will show your gravatar)
 
Please add 7 and 2 and type the answer here: