Configure ASP.NET Medium Trust for IPWorks Components


ASP.NET medium trust environments restrict certain permissions required by /n software components, which can prevent them from functioning correctly. This article explains how to configure a custom trust policy to grant the necessary permissions.

This MSDN article: "How To: Use Medium Trust in ASP.NET 2.0" discusses working in and configuring medium trust permissions. By default, ASP.NET applications run with full trust, allowing broad access to system resources, while medium trust applies restrictions using Code Access Security (CAS) through the trust element in web.config.

Here are some key points about medium trust:

  • Full trust allows unrestricted access to system resources
  • Medium trust limits permissions such as ReflectionPermission, FileIOPermission, and external resource access
  • Trust level is configured via trust level="Medium"
  • originUrl can restrict accessible endpoints
  • Custom policies can extend medium trust permissions

For the most part, shared hosting environments use medium trust by default.

All /n software .NET components require the following permissions:

  • FileIOPermission (licensing and file access)
  • ReflectionPermission (licensing)
  • SocketPermission (network communication)
  • DnsPermission (hostname resolution)

Since SocketPermission is not granted by default, a custom trust level must be defined.

On shared hosting, you typically cannot modify the main configuration, so define a custom trust level in your application's web.config:

<configuration>
    <system.web>
        <securityPolicy>
                <trustLevel name="Custom" policyFile="web_customtrust.config" />
        </securityPolicy>
        <trust level="Custom" originUrl="" /> 
...

Next, create a custom policy file (web_customtrust.config) and configure it:

<configuration>
    <mscorlib>
        <security>
            <policy>
                <PolicyLevel version="1">
                    <SecurityClasses>
                        <SecurityClass Name="AllMembershipCondition" Description="System.Security.Policy.AllMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="AspNetHostingPermission" Description="System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="DnsPermission" Description="System.Net.DnsPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="EnvironmentPermission" Description="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="FileIOPermission" Description="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="FirstMatchCodeGroup" Description="System.Security.Policy.FirstMatchCodeGroup, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="IsolatedStorageFilePermission" Description="System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="NamedPermissionSet" Description="System.Security.NamedPermissionSet"/>
                        <SecurityClass Name="PrintingPermission" Description="System.Drawing.Printing.PrintingPermission, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
                        <SecurityClass Name="SecurityPermission" Description="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="SmtpPermission" Description="System.Net.Mail.SmtpPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="SqlClientPermission" Description="System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="StrongNameMembershipCondition" Description="System.Security.Policy.StrongNameMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="UIPermission" Description="System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="UnionCodeGroup" Description="System.Security.Policy.UnionCodeGroup, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="UrlMembershipCondition" Description="System.Security.Policy.UrlMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="WebPermission" Description="System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="ZoneMembershipCondition" Description="System.Security.Policy.ZoneMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <SecurityClass Name="ReflectionPermission" Description="System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
                        <font color="red"><b><SecurityClass Name="SocketPermission" Description="System.Net.SocketPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/></b></font>
                     </SecurityClasses>

                    <NamedPermissionSets>
                        <PermissionSet class="NamedPermissionSet" version="1" Unrestricted="true" Name="FullTrust" Description="Allows full access to all resources"/>
                        <PermissionSet class="NamedPermissionSet" version="1" Name="Nothing" Description="Denies all resources, including the right to execute"/>
                        <PermissionSet class="NamedPermissionSet" version="1" Name="ASP.Net">
                            <IPermission class="AspNetHostingPermission" version="1" Level="Medium"/>
                            <IPermission class="DnsPermission" version="1" Unrestricted="true"/>
                            <IPermission class="EnvironmentPermission" version="1" Read="TEMP;TMP;USERNAME;OS;COMPUTERNAME"/>
                            <IPermission class="FileIOPermission" version="1" Read="$AppDir$" Write="$AppDir$" Append="$AppDir$" PathDiscovery="$AppDir$"/>
                            <IPermission class="IsolatedStorageFilePermission" version="1" Allowed="AssemblyIsolationByUser" UserQuota="9223372036854775807"/>
                            <IPermission class="PrintingPermission" version="1" Level="DefaultPrinting"/>
                            <IPermission class="SecurityPermission" version="1" Flags="Assertion, Execution, ControlThread,
                              ControlPrincipal, RemotingConfiguration, <font color="red"><b>SkipVerification, UnmanagedCode, SerializationFormatter</b></font>"/>
                            <IPermission class="SmtpPermission" version="1" Access="Connect"/>
                            <IPermission class="SqlClientPermission" version="1" Unrestricted="true"/>
                            <IPermission class="WebPermission" version="1">
                                <ConnectAccess>
                                    <URI uri="$OriginHost$"/>
                                </ConnectAccess>
                            </IPermission>
                            <font color="red"><b><IPermission class="SocketPermission" version="1" Unrestricted="true" /></b></font>
                            <IPermission class="ReflectionPermission" version="1" Flags="RestrictedMemberAccess"/>
                         </PermissionSet>
                    </NamedPermissionSets>
                    <CodeGroup class="FirstMatchCodeGroup" version="1" PermissionSetName="Nothing">
                        <IMembershipCondition class="AllMembershipCondition" version="1"/>
                        <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="ASP.Net">
                            <IMembershipCondition class="UrlMembershipCondition" version="1" Url="$AppDirUrl$/*"/>
                        </CodeGroup>
                        <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="ASP.Net">
                            <IMembershipCondition class="UrlMembershipCondition" version="1" Url="$CodeGen$/*"/>
                        </CodeGroup>
                        <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="Nothing">
                            <IMembershipCondition class="ZoneMembershipCondition" version="1" Zone="MyComputer"/>
                            <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="Microsoft_Strong_Name" Description="This code group grants code signed with the Microsoft strong name full trust. ">
                                <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AE
                                C8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A124365
                                18206DC093344D5AD293"/>
                            </CodeGroup>
                            <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="Ecma_Strong_Name" Description="This code group grants code signed with the ECMA strong name full trust. ">
                                <IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="00000000000000000400000000000000"/>
                            </CodeGroup>
                        </CodeGroup>
                    </CodeGroup>
                </PolicyLevel>
            </policy>
        </security>
    </mscorlib>
</configuration>

Note: If you copy and paste the above example verify that values are not incorrectly line wrapped or you may encounter unexpected compilation errors.

There are three key differences between this custom security policy and the default medium trust level. The policy adds SocketPermission in the SecurityClasses section and configures it as unrestricted in NamedPermissionSets.

It also extends SecurityPermission to include SkipVerification, UnmanagedCode, and SerializationFormatter. SkipVerification and UnmanagedCode are required for unmanaged cryptography, while SerializationFormatter supports the standard .NET licensing scheme.

By default, components that use SSL, SSH, AES, or other cryptographic operations rely on Microsoft CryptoAPI, which requires unmanaged code access. To use a fully managed implementation instead:

component.Config("UseManagedSecurityAPI=true");

When enabled, SkipVerification and UnmanagedCode are not required.

Ensure no system DLL (e.g., nsoftware.IPWorks.System.dll) exists in the /bin directory when using the managed implementation, as this may force unmanaged execution.

To support this licensing method, ensure the following permission is included:

<IPermission class="SecurityPermission" version="1" Flags="Assertion, Execution, ControlThread, ControlPrincipal, RemotingConfiguration, SkipVerification, UnmanagedCode, SerializationFormatter"/>

Note: Visual Studio may automatically add this DLL if referenced. Instead, manually place required DLLs in the /bin directory and by default, the component uses the Microsoft .NET licensing scheme.

To compile the license:

  • Add the component to the licenses.licx file
  • Build runtime licenses
  • Deploy the generated App_Licenses.dll in the /bin directory

Alternatively, a runtime license may be passed directly to the component constructor. For more information, contact support@nsoftware.com

We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.