More Efficient Deployments to a Remote Server
In my scenario, the Web server that my deployments live on is not in my office. I access it remotely via VPN and then use Remote Desktop to get to the Web server. I have medium speed DSL. My full application with all of the dynamic assemblies is now about 12MB. If I make one little change to my main executable, which is only about 500KB, I sure don't want to have to copy the entire 12MB up to the server. I am a woman of very little patience, you see. So I finally figured out a more efficient way to deploy my application.
|Don't overlook the pages of the MSDN Documentation called "Troubleshooting ClickOnce Deployments".|
Rather than do all of the manifest updates on my own computer, I finally smartened up and am doing them on the Web server. Therefore, the only files I need to transfer to the server are the ones that changed. I copied the MAGEUI.exe and my certificate for signing up to the Web server, then installed the certificate into the server's certificate store.
Once I copy the 12MB folder directly on the Web server the first time, each subsequent time I only need to copy the new file(s) from my computer to the Web server's new folder. Now I can run MAGEUI to update the application and deployment manifests remotely.
This has cut my deployment time by at least 75 percent, which of course leaves me more time for blogging!
What About a Shared Host Web Application?
This solution won't work in a scenario where you are on a shared Web host and cannot run applications like MAGEUI. You will have to prepare the complete manifest locally and then FTP the new folder and files up to your Web server. Another option, still copying all of the files, is to use the remote publishing that ClickOnce offers. I have found this to be too complex and too filled with caveats.
Semi-securing Your Installation with Forms Authentication
Semi-securing doesn't sound too comforting, but I prefer it over this text in the MSDN documentation for ClickOnce: "...if you are deploying offline applications, any authentication scenario besides Windows NT authentication is unsupported. An acceptable solution would be to allow any user to install the application, but have the client application authenticate the user by means of Web services at activation."
I was not happy when I read that. In fact, I wrote a long rant in my blog about this limitation. The driving reason behind my persistence to make this technology work for nearly four years is to enable remote employees who do not have access to (or accounts on) the domain to be able to easily install and update the application. This recommendation looked like a serious show-stopper.
Know the Risks
|The driving reason behind my persistence to make this technology work for nearly four years is to enable remote employees who do not have access to (or accounts on) the domain to be able to easily install and update the application.|
I understand Microsoft's reasoning and do not take security lightly. Besides the issue regarding cookies that is noted in the MSDN documentation: "ClickOnce uses persistent cookies; these present a security risk because they reside in the Internet Explorer cache and can be hacked,"
I've been warned of another possible hack (that I can't figure out how to do myself).
My application already uses Web services and WS-Security for authentication. Therefore, even if someone could install the application, they cannot use the application without appropriate credentials.
Nevertheless, I was adamant about not just letting anyone download and install my application, even though I knew that I couldn't protect myself from serious evil-doers. So I secured my installation portal with Forms Authentication using ASP.NET 2.0's membership APIs.
The key to hiding your manifests behind Forms Authentication is to ensure that ASP.NET knows to handle these files as they would any other ASP.NET files. The file extensions for your manifests (.application, .manifest, .deploy) are not inherently recognized by ASP.NET. Therefore, by default, ASP.NET will serve these files up without authenticating, just as they would an image file. The ISAPI mappings in IIS are responsible for this. There is an explicit list of file types that IIS is instructed to handle with the aspnet_isapi
executable when ASP.NET 2.0 initially configures IIS for your application, which means they will get processed with the ASP.NET rules. Therefore, if you want your non-ASP.NET files to also be handled by aspnet_isapi
, you need to tell IIS.
The following instructions describe how to do this with IIS6. Check out this QuickStart article
for more detailed information.
|Figure 5: Protecting non-ASP.NET 2.0 files when your site uses Forms Authentication requires telling IIS to map additional file extensions to aspnet_isape.exe. I took the blanket approach by protecting all files with a wildcard application mapping, then used the <location> element in my web.config to free up files in my images folder.|
- Ensure that your application's authorization is configured to deny all anonymous users. You can do this in web.config or use the ASP.NET Web Site configuration tool. The result in web.config is that you will see this tag in the authorization section.
<deny users= "?"/>
- In the properties of the virtual directory of your deployment Web application, enter the application configuration by clicking on the Configuration button.
- You will make an entry in the lower area of the screen: Wildcard application maps. In order to get the correct path of the aspnet_isapi file, the simplest method is to edit the .aspx application extension in the top portion of the page so that you can copy the exact file path. Then insert a new Wildcard application mapping and paste the full path of the aspnet_isapi.exe into the "Executable" text box. Be sure to select the "Verify that file exists" checkbox. Figure 5 shows the result.
- The effect of this is that EVERY file in your application will now live under the ASP.NET rules. "Every file" also means images, which was an immediately obvious problem for me. I have an image on the default login page of my deployment Web site but it would not show up because of this rule. You can easily correct this situation.
- Create a folder in your directory to store any files, such as images, that you want anonymous users to have access to. I only needed to do this with images, so I have a folder called imagesanon.
- In web.config, add a location section inside the <configuration> tags that looks like this: