Thursday, July 21, 2011

Security Exception - Medium trust ASP.NET application consumes an external web service

you will encounter the below error if your asp.net application uses a medium trust level (<trust level="medium">) and it tries to consume an external web service.


Description: The application attempted to perform an operation not allowed by the security policy.  To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file. 

Exception Details: System.Security.SecurityException: Request for the permission of type 'System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.



[SecurityException: Request for the permission of type 'System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]
   System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet) +0
   System.Security.CodeAccessPermission.Demand() +58
   System.Net.HttpWebRequest..ctor(Uri uri, ServicePoint servicePoint) +147
   System.Net.HttpRequestCreator.Create(Uri Uri) +26
   System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase) +216
   System.Net.WebRequest.Create(Uri requestUri) +31
   System.Web.Services.Protocols.WebClientProtocol.GetWebRequest(Uri uri) +32
   System.Web.Services.Protocols.HttpWebClientProtocol.GetWebRequest(Uri uri) +15
   System.Web.Services.Protocols.SoapHttpClientProtocol.GetWebRequest(Uri uri) +4
   System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +52
   myService.MyWebMethod() in App_WebReferences.tbvx_k59.3.cs:153
   Positions.Page_Load(Object sender, EventArgs e)
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +50
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6785
   System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +242
   System.Web.UI.Page.ProcessRequest() +80
   System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +21
   System.Web.UI.Page.ProcessRequest(HttpContext context) +49
   ASP.careers_positions_aspx.ProcessRequest(HttpContext context) in App_Web_x4ylsrid.0.cs:0
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Why this happens?

By default, medium-trust policy grants ASP.NET Web applications a restricted WebPermission

Resolution:


To be able to call Web services from your Web application, you must configure the originUrl attribute on your application's <trust> element.


To call a single Web service from a medium trust Web application
  1. Configure the application to run at medium trust.
  2. Set the originUrl to point to the Web service you want to be able to call, as follows:
    <trust level="Medium" originUrl="http://servername/.*"/>
    
The originUrl value is used in the constructor for a System.Text.RegEx regular expression class so that in can perform a match on the URLs that are accessible by the Web service. This RegEx class is used in conjunction with a WebPermission class. The ".*" matches any URL beginning with "http://servername/".
The originUrl attribute is used when ASP.NET policy is evaluated. It gives a value for the $OriginHost$ substitution parameter. Here is the WebPermissiondefinition from Web_mediumtrust.config:
<IPermission
   class="WebPermission"
   version="1">
   <ConnectAccess>
     <URI uri="$OriginHost$"/>
   </ConnectAccess>
</IPermission>
If you do not specify the Web servers accessed by your application, any Web service request will fail with a SecurityException. To call a Web service on the local Web server, use the following configuration:
<trust level="Medium" originUrl="http://localhost/.*" />
If your application needs to access multiple Web services on different servers, you need to customize ASP.NET policy because you can only specify one originUrlon the <trust> element in Web.config or Machine.config.
To call multiple Web services from a medium-trust application
  1. Copy the Web_mediumtrust.config file, which is in the following directory, to a file called Web_mediumtrust_WebService.config, which is located in the same directory.
    %windir%\Microsoft.NET\Framework\{version}\CONFIG
    
  2. Locate WebPermission and add a <URI> element for each server you will be accessing, as follows:
    <IPermission class="WebPermission" version="1">
      <ConnectAccess>
        <URI uri="$OriginHost$"/>
        <URI uri="http://server1/.*"/>
        <URI uri="http://server2/.*"/>
        <URI uri="http://server3/.*"/>
      </ConnectAccess>
    </IPermission>
    
    If you call the Web service using its NetBIOS) name, DNS name, and/or IP address, you must have a separate <URI> element for each URI as shown in the following example.
    <IPermission class="WebPermission" version="1">
      <ConnectAccess>
        <URI uri="$OriginHost$"/>
        <URI uri="http://servername.yourDomain.com/.*"/>
        <URI uri="http:// servername/.*"/>
        <URI uri="http://127.0.0.1/.*"/>
      </ConnectAccess>
    </IPermission>
    
  3. Save the file.
  4. Update your application's Web.config file to point to the newly created policy file. This requires that you create a new trust level and map it to the new policy file. Next, configure the <trust> element of your application to use the new level.
    The following fragment shows the necessary additions to Web.config:
    <system.web>
      <securityPolicy>
        <trustLevel name="MediumPlusWebPermission" 
                    policyFile="web_mediumtrust_WebService.config"/>
      </securityPolicy>
      <trust level=" MediumPlusWebPermission" originUrl=""/>
    </system.web>
    Source: http://msdn.microsoft.com/en-us/library/Aa302425
    
    
    Happy coding!

No comments:

Post a Comment