You should split your application into three parts:
Windows Service
This would host a WCF or Remoting application. You want to put the code that requires privileged access to your system in here. For example creating and deleting websites. Run this service under an account that has enough rights to perform operations using Microsoft.Web.Administration
.
Trusted Wrapper or Proxy Assembly
This is just a signed wrapper assembly that is installed in the GAC. Its role is to pass on calls from your low trust web application to perform privileged actions in the code running in the service above. Mark the assembly with the AllowPartiallyTrustedCallers
attribute (if your server is configured for partial trust) and mark any classes that require access to the remoting service with [PermissionSet(SecurityAction.Assert, Unrestricted=true)]
.
Front End Application(or Web Service)
This is the interface to your application (whether it be a web application with a GUI or a web service). Run this in its own application pool with just enough rights to execute, for example IUSR
or a similar account. Ideally you should also run this under partial trust.
Your web application/service references the Trusted Wrapper assembly in the GAC which in turn has a reference to the remoting or WCF application running in the windows service.
Using this layered approach means that you are locking down by gating access to specific privileged operations which only run in your windows service.
This approach is covered quite well in Appendix C of Dominick Baier's 'Developing More-Secure Microsoft ASP.NET 2.0 Applications'. I thoroughly recommend getting a copy.