Beveiliging van codetoegang en ADO.NET

.NET Framework biedt beveiliging op basis van rollen en CAS (Code Access Security), die beide worden geïmplementeerd met behulp van een gemeenschappelijke infrastructuur die wordt geleverd door de Common Language Runtime (CLR). In de wereld van onbeheerde code worden de meeste toepassingen uitgevoerd met de machtigingen van de gebruiker of principal. Als gevolg hiervan kunnen computersystemen beschadigd raken en persoonlijke gegevens worden aangetast wanneer schadelijke of fout gevulde software wordt uitgevoerd door een gebruiker met verhoogde bevoegdheden.

Beheerde code die in .NET Framework wordt uitgevoerd, bevat daarentegen beveiliging voor codetoegang, die alleen van toepassing is op code. Of de code al dan niet mag worden uitgevoerd, is afhankelijk van de oorsprong van de code of andere aspecten van de identiteit van de code, niet alleen de identiteit van de principal. Dit vermindert de kans dat beheerde code kan worden misbruikt.

Notitie

Cas (Code Access Security) is afgeschaft in alle versies van .NET Framework en .NET. Recente versies van .NET respecteren geen CAS-aantekeningen en produceren fouten als CAS-gerelateerde API's worden gebruikt. Ontwikkelaars moeten alternatieve manieren zoeken om beveiligingstaken uit te voeren.

Machtigingen voor codetoegang

Wanneer code wordt uitgevoerd, geeft het bewijs weer dat wordt geëvalueerd door het CLR-beveiligingssysteem. Dit bewijs bestaat doorgaans uit de oorsprong van de code, inclusief URL, site en zone en digitale handtekeningen die de identiteit van de assembly garanderen.

Met de CLR kan code alleen bewerkingen uitvoeren waarvoor de code is gemachtigd om uit te voeren. Code kan machtigingen aanvragen en deze aanvragen worden uitgevoerd op basis van het beveiligingsbeleid dat is ingesteld door een beheerder.

Notitie

Code die wordt uitgevoerd in de CLR, kan geen machtigingen aan zichzelf verlenen. Code kan bijvoorbeeld minder machtigingen aanvragen en krijgen dan een beveiligingsbeleid toestaat, maar er worden nooit meer machtigingen verleend. Wanneer u machtigingen verleent, begint u met helemaal geen machtigingen en voegt u vervolgens de smalste machtigingen toe voor de specifieke taak die wordt uitgevoerd. Beginnen met alle machtigingen en vervolgens weigeren van afzonderlijke toepassingen leidt tot onveilige toepassingen die onbedoelde beveiligingsgaten kunnen bevatten om meer machtigingen te verlenen dan vereist. Zie Het configureren van beveiligingsbeleid en beveiligingsbeleidsbeheer voor meer informatie.

Er zijn drie typen machtigingen voor codetoegang:

  • Code access permissions afgeleid van de CodeAccessPermission klasse. Machtigingen zijn vereist om toegang te krijgen tot beveiligde resources, zoals bestanden en omgevingsvariabelen, en om beveiligde bewerkingen uit te voeren, zoals toegang tot niet-beheerde code.

  • Identity permissions kenmerken vertegenwoordigen die een assembly identificeren. Machtigingen worden verleend aan een assembly op basis van bewijs, waaronder items zoals een digitale handtekening of waar de code vandaan komt. Identiteitsmachtigingen zijn ook afgeleid van de CodeAccessPermission basisklasse.

  • Role-based security permissions zijn gebaseerd op of een principal een opgegeven identiteit heeft of lid is van een opgegeven rol. De PrincipalPermission klasse staat zowel declaratieve als imperatieve machtigingscontroles toe aan de actieve principal.

Om te bepalen of code is gemachtigd om toegang te krijgen tot een resource of een bewerking uit te voeren, gaat het beveiligingssysteem van de runtime door de aanroepstack, waarbij de verleende machtigingen van elke aanroeper worden vergeleken met de machtiging die wordt gevraagd. Als een beller in de oproepstack niet over de vereiste machtiging beschikt, wordt er een SecurityException gegenereerd en wordt de toegang geweigerd.

Machtigingen aanvragen

Het doel van het aanvragen van machtigingen is om de runtime te informeren over welke machtigingen uw toepassing nodig heeft om uit te voeren en om ervoor te zorgen dat deze alleen de machtigingen ontvangt die het daadwerkelijk nodig heeft. Als uw toepassing bijvoorbeeld gegevens naar de lokale schijf moet schrijven, is dit vereist FileIOPermission. Als deze machtiging niet is verleend, mislukt de toepassing wanneer wordt geprobeerd naar de schijf te schrijven. Als de toepassing echter aanvraagt FileIOPermission en die machtiging niet is verleend, genereert de toepassing de uitzondering aan het begin en wordt deze niet geladen.

In een scenario waarin de toepassing alleen gegevens van de schijf hoeft te lezen, kunt u aanvragen dat deze nooit schrijfmachtigingen krijgt. In het geval van een bug of een schadelijke aanval kan uw code de gegevens waarop deze werkt, niet beschadigen. Zie Machtigingen aanvragen voor meer informatie.

Beveiliging op basis van rollen en CAS

Door zowel op rollen gebaseerde beveiliging als cas (code-accessed security) te implementeren, wordt de algehele beveiliging voor uw toepassing verbeterd. Beveiliging op basis van rollen kan worden gebaseerd op een Windows-account of een aangepaste identiteit, waardoor informatie over de beveiligingsprincipaal beschikbaar is voor de huidige thread. Bovendien zijn toepassingen vaak vereist om toegang te bieden tot gegevens of resources op basis van referenties die door de gebruiker zijn opgegeven. Normaal gesproken controleren dergelijke toepassingen de rol van een gebruiker en bieden ze toegang tot resources op basis van deze rollen.

Met op rollen gebaseerde beveiliging kan een onderdeel huidige gebruikers en hun bijbehorende rollen tijdens runtime identificeren. Deze informatie wordt vervolgens toegewezen met behulp van een CAS-beleid om de set machtigingen te bepalen die tijdens runtime zijn verleend. Voor een opgegeven toepassingsdomein kan de host het standaardbeveiligingsbeleid op basis van rollen wijzigen en een standaardbeveiligingsprincipaal instellen dat een gebruiker en de rollen vertegenwoordigt die aan die gebruiker zijn gekoppeld.

De CLR gebruikt machtigingen voor het implementeren van het mechanisme voor het afdwingen van beperkingen voor beheerde code. Beveiligingsmachtigingen op basis van rollen bieden een mechanisme voor het detecteren of een gebruiker (of de agent die namens de gebruiker handelt) een bepaalde identiteit heeft of lid is van een opgegeven rol. Zie Beveiligingsmachtigingen voor meer informatie.

Afhankelijk van het type toepassing dat u bouwt, moet u ook overwegen om machtigingen op basis van rollen in de database te implementeren. Zie SQL Server-beveiliging voor meer informatie over beveiliging op basis van rollen in SQL Server.

Assembly's

Assembly's vormen de fundamentele eenheid van implementatie, versiebeheer, hergebruik, activeringsbereik en beveiligingsmachtigingen voor een .NET Framework-toepassing. Een assembly biedt een verzameling typen en resources die zijn gebouwd om samen te werken en een logische eenheid van functionaliteit te vormen. Voor de CLR bestaat een type niet buiten de context van een assembly. Zie Programmeren met assembly's voor meer informatie over het maken en implementeren van assembly's.

Naamgevingsassembly's

Een sterke naam, of digitale handtekening, bestaat uit de identiteit van de assembly, waaronder de eenvoudige tekstnaam, versienummer en cultuurinformatie (indien opgegeven), plus een openbare sleutel en een digitale handtekening. De digitale handtekening wordt gegenereerd op basis van een assemblybestand met behulp van de bijbehorende persoonlijke sleutel. Het assemblybestand bevat het assemblymanifest, dat de namen en hashes bevat van alle bestanden waaruit de assembly bestaat.

Sterke naamgeving van een assembly geeft een toepassing of onderdeel een unieke identiteit die andere software kan gebruiken om er expliciet naar te verwijzen. Sterke naamgeving beschermt assembly's tegen spoofed door een assembly die vijandige code bevat. Sterke naamgeving zorgt er ook voor dat versiebeheer consistent is tussen verschillende versies van een onderdeel. U moet sterke naamassembly's gebruiken die worden geïmplementeerd in de Global Assembly Cache (GAC). Zie Voor meer informatie het maken en gebruiken van sterk benoemde assembly's.

Gedeeltelijk vertrouwen in ADO.NET 2.0

In ADO.NET 2.0 kunnen de .NET Framework-gegevensprovider voor SQL Server, de .NET Framework-gegevensprovider voor OLE DB, de .NET Framework-gegevensprovider voor ODBC en de .NET Framework-gegevensprovider voor Oracle nu allemaal worden uitgevoerd in gedeeltelijk vertrouwde omgevingen. In eerdere versies van .NET Framework werd alleen System.Data.SqlClient ondersteund in toepassingen met minder dan volledig vertrouwen.

Minimaal moet een gedeeltelijk vertrouwde toepassing die gebruikmaakt van de SQL Server-provider, beschikken over uitvoerings- en SqlClientPermission machtigingen.

Eigenschappen van machtigingskenmerk voor gedeeltelijke vertrouwensrelatie

Voor gedeeltelijke vertrouwensscenario's kunt u leden gebruiken SqlClientPermissionAttribute om de mogelijkheden die beschikbaar zijn voor de .NET Framework-gegevensprovider voor SQL Server verder te beperken.

De volgende tabel bevat de beschikbare SqlClientPermissionAttribute eigenschappen en de bijbehorende beschrijvingen:

Eigenschap Machtigingskenmerk Beschrijving
Action Hiermee haalt u een beveiligingsactie op of stelt u deze in. Overgenomen van SecurityAttribute.
AllowBlankPassword Hiermee schakelt u het gebruik van een leeg wachtwoord in of uit in een verbindingsreeks. Geldige waarden zijn true (om het gebruik van lege wachtwoorden in te schakelen) en false (om het gebruik van lege wachtwoorden uit te schakelen). Overgenomen van DBDataPermissionAttribute.
ConnectionString Identificeert een toegestane verbindingsreeks. Er kunnen meerdere verbindingsreeks worden geïdentificeerd. Opmerking: voeg geen gebruikers-id of wachtwoord toe aan uw verbindingsreeks. In deze release kunt u verbindingsreeks beperkingen niet wijzigen met behulp van het .NET Framework Configuration Tool.

Overgenomen van DBDataPermissionAttribute.
KeyRestrictions Identificeert verbindingsreeks parameters die zijn toegestaan of niet zijn toegestaan. Verbinding maken iontekenreeksparameters worden geïdentificeerd in het formulier <parameternaam>=. Er kunnen meerdere parameters worden opgegeven, gescheiden met behulp van een puntkomma (;). Opmerking: Als u niet opgeeftKeyRestrictions, maar u de eigenschap AllowOnly instelt KeyRestrictionBehavior op ofPreventUsage, zijn er geen aanvullende verbindingsreeks parameters toegestaan. Overgenomen van DBDataPermissionAttribute.
KeyRestrictionBehavior Identificeert de verbindingsreeks parameters als de enige aanvullende parameters die zijn toegestaan (AllowOnly) of identificeert de aanvullende parameters die niet zijn toegestaan (PreventUsage). AllowOnly is de standaardwaarde. Overgenomen van DBDataPermissionAttribute.
TypeID Hiermee haalt u een unieke id voor dit kenmerk op wanneer deze wordt geïmplementeerd in een afgeleide klasse. Overgenomen van Attribute.
Unrestricted Hiermee wordt aangegeven of onbeperkte machtigingen voor de resource zijn gedeclareerd. Overgenomen van SecurityAttribute.

Verbinding maken ionString-syntaxis

In het volgende voorbeeld ziet u hoe u het connectionStrings element van een configuratiebestand gebruikt, zodat alleen een specifieke verbindingsreeks kan worden gebruikt. Zie Verbinding maken ion Strings voor meer informatie over het opslaan en ophalen van verbindingsreeks s uit configuratiebestanden.

<connectionStrings>  
  <add name="DatabaseConnection"
    connectionString="Data Source=(local);Initial
    Catalog=Northwind;Integrated Security=true;" />  
</connectionStrings>  

KeyRestrictions-syntaxis

In het volgende voorbeeld worden dezelfde verbindingsreeks ingeschakeld, wordt het gebruik van de Encrypt en Packet Size verbindingsreeks opties ingeschakeld, maar wordt het gebruik van andere verbindingsreeks opties beperkt.

<connectionStrings>  
  <add name="DatabaseConnection"
    connectionString="Data Source=(local);Initial
    Catalog=Northwind;Integrated Security=true;"  
    KeyRestrictions="Encrypt=;Packet Size=;"  
    KeyRestrictionBehavior="AllowOnly" />  
</connectionStrings>  

KeyRestrictionBehavior met PreventUsage Syntaxis

In het volgende voorbeeld worden dezelfde verbindingsreeks ingeschakeld en worden alle andere verbindingsparameters toegestaan, met uitzondering van User Id, Password en Persist Security Info.

<connectionStrings>  
  <add name="DatabaseConnection"
    connectionString="Data Source=(local);Initial
    Catalog=Northwind;Integrated Security=true;"  
    KeyRestrictions="User Id=;Password=;Persist Security Info=;"  
    KeyRestrictionBehavior="PreventUsage" />  
</connectionStrings>  

KeyRestrictionBehavior met AllowOnly-syntaxis

In het volgende voorbeeld worden twee verbindingsreeks die ook parameters bevatten, Connection TimeoutEncrypten Packet Size parameters bevattenInitial Catalog. Alle andere verbindingsreeks parameters zijn beperkt.

<connectionStrings>  
  <add name="DatabaseConnection"
    connectionString="Data Source=(local);Initial
    Catalog=Northwind;Integrated Security=true;"  
    KeyRestrictions="Initial Catalog;Connection Timeout=;  
       Encrypt=;Packet Size=;"
    KeyRestrictionBehavior="AllowOnly" />  
  
  <add name="DatabaseConnection2"
    connectionString="Data Source=SqlServer2;Initial
    Catalog=Northwind2;Integrated Security=true;"  
    KeyRestrictions="Initial Catalog;Connection Timeout=;  
       Encrypt=;Packet Size=;"
    KeyRestrictionBehavior="AllowOnly" />  
</connectionStrings>  

Gedeeltelijke vertrouwensrelatie inschakelen met een aangepaste machtigingenset

Als u het gebruik van System.Data.SqlClient machtigingen voor een bepaalde zone wilt inschakelen, moet een systeembeheerder een aangepaste machtigingenset maken en instellen als de machtigingenset voor een bepaalde zone. Standaardmachtigingenets, zoals LocalIntranet, kunnen niet worden gewijzigd. Als u bijvoorbeeld machtigingen wilt opnemen System.Data.SqlClient voor code met een Zone van LocalIntranet, kan een systeembeheerder de machtigingenset LocalIntranetkopiëren, de naam ervan wijzigen in CustomLocalIntranet, de System.Data.SqlClient machtigingen toevoegen, de customLocalIntranet-machtigingenset importeren met behulp van het Caspol.exe (hulpprogramma voor beveiligingsbeleid voor codetoegang) en de machtigingenset LocalIntranet_Zone instellen op CustomLocalIntranet.

Voorbeeldmachtigingsset

Hier volgt een voorbeeldmachtigingsset voor de .NET Framework-gegevensprovider voor SQL Server in een gedeeltelijk vertrouwd scenario. Zie Machtigingensets configureren met behulp van Caspol.exe voor meer informatie over het maken van aangepaste machtigingensets.

<PermissionSet class="System.Security.NamedPermissionSet"  
  version="1"  
  Name="CustomLocalIntranet"  
  Description="Custom permission set given to applications on  
    the local intranet">  
  
<IPermission class="System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"  
version="1"  
AllowBlankPassword="False">  
<add ConnectionString="Data Source=(local);Integrated Security=true;"  
 KeyRestrictions="Initial Catalog=;Connection Timeout=;  
   Encrypt=;Packet Size=;"
 KeyRestrictionBehavior="AllowOnly" />  
 </IPermission>  
</PermissionSet>  

Toegang tot ADO.NET code controleren met behulp van beveiligingsmachtigingen

Voor scenario's met gedeeltelijke vertrouwensrelaties kunt u CAS-bevoegdheden voor bepaalde methoden in uw code vereisen door een SqlClientPermissionAttribute. Als deze bevoegdheid niet is toegestaan door het beperkte beveiligingsbeleid, wordt er een uitzondering gegenereerd voordat uw code wordt uitgevoerd. Zie Aanbevolen procedures voor beveiligingsbeleid enaanbevolen procedures voor beveiligingsbeleid voor meer informatie over beveiligingsbeleid.

Opmerking

In het volgende voorbeeld ziet u hoe u code schrijft waarvoor een bepaalde verbindingsreeks is vereist. Het simuleert het weigeren van onbeperkte machtigingen waarvoor System.Data.SqlClienteen systeembeheerder zou implementeren met behulp van een CAS-beleid in de echte wereld.

Belangrijk

Bij het ontwerpen van CAS-machtigingen voor ADO.NET is het juiste patroon om te beginnen met het meest beperkende geval (helemaal geen machtigingen) en vervolgens de specifieke machtigingen toe te voegen die nodig zijn voor de specifieke taak die door de code moet worden uitgevoerd. Het tegenovergestelde patroon, te beginnen met alle machtigingen en vervolgens een specifieke machtiging weigeren, is niet veilig omdat er veel manieren zijn om dezelfde verbindingsreeks uit te drukken. Als u bijvoorbeeld begint met alle machtigingen en vervolgens probeert het gebruik van de verbindingsreeks 'server=someserver' te weigeren, is de tekenreeks 'server=someserver.mycompany.com' nog steeds toegestaan. Door altijd te beginnen met het verlenen van geen machtigingen, vermindert u de kans dat er gaten in de machtigingenset zijn.

De volgende code laat zien hoe SqlClient de beveiligingsvraag wordt uitgevoerd, wat een SecurityException werpt als de juiste CAS-machtigingen niet aanwezig zijn. De SecurityException uitvoer wordt weergegeven in het consolevenster.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Security;
using System.Security.Permissions;

namespace PartialTrustTopic {
   public class PartialTrustHelper : MarshalByRefObject {
      public void TestConnectionOpen(string connectionString) {
         // Try to open a connection.
         using (SqlConnection connection = new SqlConnection(connectionString)) {
            connection.Open();
         }
      }
   }

   class Program {
      static void Main(string[] args) {
         TestCAS("Data Source=(local);Integrated Security=true", "Data Source=(local);Integrated Security=true;Initial Catalog=Test");
      }

      static void TestCAS(string connectString1, string connectString2) {
         // Create permission set for sandbox AppDomain.
         // This example only allows execution.
         PermissionSet permissions = new PermissionSet(PermissionState.None);
         permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

            // Create sandbox AppDomain with permission set that only allows execution,
            // and has no SqlClientPermissions.
            AppDomainSetup appDomainSetup = new AppDomainSetup();
         appDomainSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
         AppDomain firstDomain = AppDomain.CreateDomain("NoSqlPermissions", null, appDomainSetup, permissions);

         // Create helper object in sandbox AppDomain so that code can be executed in that AppDomain.
         Type helperType = typeof(PartialTrustHelper);
         PartialTrustHelper firstHelper = (PartialTrustHelper)firstDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName);

         try {
            // Attempt to open a connection in the sandbox AppDomain.
            // This is expected to fail.
            firstHelper.TestConnectionOpen(connectString1);
            Console.WriteLine("Connection opened, unexpected.");
         }
         catch (System.Security.SecurityException ex) {
            Console.WriteLine("Failed, as expected: {0}",
                ex.FirstPermissionThatFailed);

            // Uncomment the following line to see Exception details.
            // Console.WriteLine("BaseException: " + ex.GetBaseException());
         }

         // Add permission for a specific connection string.
         SqlClientPermission sqlPermission = new SqlClientPermission(PermissionState.None);
         sqlPermission.Add(connectString1, "", KeyRestrictionBehavior.AllowOnly);

         permissions.AddPermission(sqlPermission);

         AppDomain secondDomain = AppDomain.CreateDomain("OneSqlPermission", null, appDomainSetup, permissions);
         PartialTrustHelper secondHelper = (PartialTrustHelper)secondDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName);

         // Try connection open again, it should succeed now.
         try {
            secondHelper.TestConnectionOpen(connectString1);
            Console.WriteLine("Connection opened, as expected.");
         }
         catch (System.Security.SecurityException ex) {
            Console.WriteLine("Unexpected failure: {0}", ex.Message);
         }

         // Try a different connection string. This should fail.
         try {
            secondHelper.TestConnectionOpen(connectString2);
            Console.WriteLine("Connection opened, unexpected.");
         }
         catch (System.Security.SecurityException ex) {
            Console.WriteLine("Failed, as expected: {0}", ex.Message);
         }
      }
   }
}
Imports System.Data
Imports System.Data.SqlClient
Imports System.Security
Imports System.Security.Permissions

Namespace PartialTrustTopic
    Public Class PartialTrustHelper
        Inherits MarshalByRefObject
        Public Sub TestConnectionOpen(ByVal connectionString As String)
            ' Try to open a connection.
            Using connection As New SqlConnection(connectionString)
                connection.Open()
            End Using
        End Sub
    End Class

    Class Program
        Public Shared Sub Main(ByVal args As String())
            TestCAS("Data Source=(local);Integrated Security=true", "Data Source=(local);Integrated Security=true;Initial Catalog=Test")
        End Sub

        Public Shared Sub TestCAS(ByVal connectString1 As String, ByVal connectString2 As String)
            ' Create permission set for sandbox AppDomain.
            ' This example only allows execution.
            Dim permissions As New PermissionSet(PermissionState.None)
            permissions.AddPermission(New SecurityPermission(SecurityPermissionFlag.Execution))

            ' Create sandbox AppDomain with permission set that only allows execution,
            ' and has no SqlClientPermissions.
            Dim appDomainSetup As New AppDomainSetup()
            appDomainSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
            Dim firstDomain As AppDomain = AppDomain.CreateDomain("NoSqlPermissions", Nothing, appDomainSetup, permissions)

            ' Create helper object in sandbox AppDomain so that code can be executed in that AppDomain.
            Dim helperType As Type = GetType(PartialTrustHelper)
            Dim firstHelper As PartialTrustHelper = DirectCast(firstDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName), PartialTrustHelper)

            Try
                ' Attempt to open a connection in the sandbox AppDomain.
                ' This is expected to fail.
                firstHelper.TestConnectionOpen(connectString1)
                Console.WriteLine("Connection opened, unexpected.")
            Catch ex As System.Security.SecurityException

                ' Uncomment the following line to see Exception details.
                ' Console.WriteLine("BaseException: " + ex.GetBaseException());
                Console.WriteLine("Failed, as expected: {0}", ex.FirstPermissionThatFailed)
            End Try

            ' Add permission for a specific connection string.
            Dim sqlPermission As New SqlClientPermission(PermissionState.None)
            sqlPermission.Add(connectString1, "", KeyRestrictionBehavior.AllowOnly)

            permissions.AddPermission(sqlPermission)

            Dim secondDomain As AppDomain = AppDomain.CreateDomain("OneSqlPermission", Nothing, appDomainSetup, permissions)
            Dim secondHelper As PartialTrustHelper = DirectCast(secondDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName), PartialTrustHelper)

            ' Try connection open again, it should succeed now.
            Try
                secondHelper.TestConnectionOpen(connectString1)
                Console.WriteLine("Connection opened, as expected.")
            Catch ex As System.Security.SecurityException
                Console.WriteLine("Unexpected failure: {0}", ex.Message)
            End Try

            ' Try a different connection string. This should fail.
            Try
                secondHelper.TestConnectionOpen(connectString2)
                Console.WriteLine("Connection opened, unexpected.")
            Catch ex As System.Security.SecurityException
                Console.WriteLine("Failed, as expected: {0}", ex.Message)
            End Try
        End Sub
    End Class
End Namespace

U ziet deze uitvoer in het consolevenster:

Failed, as expected: <IPermission class="System.Data.SqlClient.  
SqlClientPermission, System.Data, Version=2.0.0.0,
  Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1"  
  AllowBlankPassword="False">  
<add ConnectionString="Data Source=(local);Initial Catalog=  
  Northwind;Integrated Security=SSPI" KeyRestrictions=""  
KeyRestrictionBehavior="AllowOnly"/>  
</IPermission>  
  
Connection opened, as expected.  
Failed, as expected: Request failed.  

Interoperabiliteit met niet-beheerde code

Code die buiten de CLR wordt uitgevoerd, wordt niet-beheerde code genoemd. Daarom kunnen beveiligingsmechanismen zoals CAS niet worden toegepast op onbeheerde code. COM-onderdelen, ActiveX-interfaces en Windows API-functies zijn voorbeelden van niet-beheerde code. Speciale beveiligingsoverwegingen zijn van toepassing bij het uitvoeren van onbeheerde code, zodat u de algehele beveiliging van toepassingen niet in gevaar brengt. Zie Interoperating with Unmanaged Code (Interoperating with Unmanaged Code) voor meer informatie.

Het .NET Framework biedt ook ondersteuning voor achterwaartse compatibiliteit met bestaande COM-onderdelen door toegang te bieden via COM-interoperabiliteit. U kunt COM-onderdelen opnemen in een .NET Framework-toepassing met behulp van COM-interoperabiliteitshulpprogramma's om de relevante COM-typen te importeren. Zodra de COM-typen zijn geïmporteerd, kunnen ze worden gebruikt. COM-interoperabiliteit stelt COM-clients ook in staat om toegang te krijgen tot beheerde code door assemblymetagegevens naar een typebibliotheek te exporteren en het beheerde onderdeel als com-onderdeel te registreren. Zie Geavanceerde COM-interoperabiliteit voor meer informatie.

Zie ook