Making cross domain web requests in asp.net with medium trust enabled
There could be plenty of reason that you might need to do a cross domain web request in your application. One could be let's say you want to divert the resource pressure from your server to some third party content provider like Amazon S3. In my last post I have mentioned a bit about uploading content using WSE to S3 server. I also mentioned about the simple library located at www.codeplex.com/threesharp that does not necessarily require you to work in full trust mode. This is also true if you have a personalized startpage where you want your wideget developers to restrict to partiuclar URLs.
Now, before starting it is worth mentioning that in medium trust mode any cross domain request is disabled by default. In other words, you can do calls only for your local endpoints.
How to get around this ?
When you install .net framework under %installed dir%\framework\version\config you will find a web_(high or medium or low)trust.config file that defines some policy about how your application will behave in a particular security level specified.
Now, to customize the default medium trust settings best is to copy it to your application directory so that you can tweaks thing only for your application and don't end up making it unstable in global scope. To show it as an example I have created a sample project that tries to do a web request, gets the data out and finally stuffs it to the response stream. To simulate, first let's put the following line in web.config which is pretty general for those of you works with it daily to strictly support medium trust in your app.
<trust level="Medium" /> // this is only for simulating in localhost
Next is to define your security level and config that will look for policies
<trustLevel name="Medium" policyFile="web_mediumtrust.config"/>
The above line will come into action only when medium trust is enabled. But here to note that if you dont have control over your hosting provider or your hosting has a <location allowOverride="false"> node in the root config then this approach won't work. Either you have to tell your hosting provider to add the requested URL for you or if you are doing things with your own hosting then you have to do it by yourself :-).
If you generally try to do a web request without any predefined policy defined in medium trust then you might see the following error
Request for the permission of type 'System.Net.WebPermission, System, Version=126.96.36.199, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
To overcome, once you have medium trust config in place you need to override the connectAccess property of WebPermission class. To do so , let's say I want to grant request for search.live.com and its descendant URLs, so the changes that I need to make looks something like the pasted.
<IPermission class="WebPermission" version="1">
The default URL for requests in medium trust config is set to $OriginHost$ which says, "Can't let you do request to domains other than your own :-)" . The URL property takes regular expression and I can grant as many as URLs I want just by adding a new URL element and associating it with proper endpoint that my API or application might call. You can download the sample here and hope that helps a bit.
Update : As most of the shared hosting are with <location allowOverride="false"> the approach is useful only if you are a system administrator or want to have full control over your site by restricting your widget developers to a limited URLs