reklama

Poznáváme C# a Microsoft .NET 77. díl – Programové použití CAS

Po teoretickém úvodu do světa bezpečnosti v .NET frameworku a představení CAS se v dnešním díle konečně podíváme na možnost využití této technologie z našeho programového kódu a to jak imperativním způsobem, tak způsobem deklarativním.

Možnosti programového použití CAS

Po minulém díle již víme, že technologie zabezpečení CAS slouží k ochraně zdrojů před nebezpečným kódem a také víme, že je tento způsob zabezpečení postaven na konfigurovatelném principu kódových skupin a sad oprávnění. Systém zabezpečení CAS jsme schopni využívat i z našeho programového kódu.

Díky této možnosti jsme například schopni zjistit zda-li běžící kód disponuje oprávněními pro přístup k určitému chráněnému zdroji a na základě toho zareagovat. A to třeba tak, že vyhodíme chybovou hlášku nebo změníme chování aplikace. Také jsme schopni například zajistit, že kód volající naši assembly bude dočasně moci přistupovat k prostředku na který nemá potřebná oprávnění a nebo je naopak možné zamítnout volajícímu kódu přistup k chráněnému prostředku i když oprávněním na přístup disponuje.

Způsoby programového použití CAS

Pracovat programově se systémem zabezpečení CAS je možné dvěma odlišnými způsoby. Prvním z nich je takzvaný imperativní, při kterém jsou standardně v kódu používány třídy systému zabezpečení CAS. Druhým způsobem je deklarativní, při jehož použití jsou používány atributy k označení typů a jejich členů, k zajištění požadované bezpečnostní funkčnosti. Nelze říci, že imperativním způsobem lze udělat to samé jako způsobem deklarativním a naopak. Řada věcí sice lze realizovat oběma způsoby, ale existuje i několik specifických věcí, které lze provést pouze jedním způsobem.

Při použití imperativního způsobu je, díky tomu, že jde o standardní volání metod na objektech, možné inicializovat objekty představující požadovaná oprávnění na základě informací, které jsou k dispozici pouze za běhu aplikace, a také je možné reagovat vlastními operacemi na případy, kdy kód nemá dostatečná oprávnění. Naproti tomu u použití deklarativního způsobu je možné provádět požadavky na potřebná minimální přidělená oprávnění a díky tomu, že je u toho způsobu použito atributů, lze informace o požadovaných oprávněních získat pomocí mechanismu reflexe. Také je použití tohoto způsobu pohodlnější, protože při něm napíšete méně kódu.

Vyžádání oprávnění

Všechna oprávnění v CAS jsou představována třídami, které implementují rozhraní IPermission ze jmenného prostoru System.Security. Dalším často implementovaným rozhraním je rozhraní IStackWalk ze stejného jmenného prostoru. Obě tato rozhraní obsahují metodu Demand, pro vyžádání daného oprávnění, ovšem pokud třída oprávnění implementuje rozhraní IStackWalk, znamená to, že při žádosti o oprávnění je procházen celý zásobník volání k ověření toho, že všichni volající mají požadované oprávnění. Většina tříd oprávnění rozhraní IStackWalk implementuje, ale jsou i výjimky typu PrincipalPermission (spojené ale spíše s role-based security), které implementují pouze rozhraní IPermission, tudíž v implementaci metody Demand zásobník volání neprocházejí. Společným předkem tříd pro práci se zdroji pomocí CAS je třída CodeAccessPermission, která implementuje obě dvě výše zmíněná rozhraní.

Při využití imperativního přístupu tedy pro vyžádání oprávnění zavoláme metodu Demand na konkrétním objektu oprávnění. Pokud mají všichni volající dostatečná oprávnění volání metody proběhne bez problému, avšak pokud některý volající nemá potřebná oprávnění je vyhozena výjimka typu SecurityException.

public class DemandExample
{
        public static void TestDemand()
        {
            IPermission perm = new EnvironmentPermission(EnvironmentPermissionAccess.Read, "PATH");
            try
            {
                //vyzadame opravneni - pokud kod opravneni nema je vyhozena vyjimka SecurityException
                perm.Demand();
                Console.WriteLine("Kod MA opravneni pro pristup k promenne prostredi PATH");
            }
            catch (SecurityException)
            {
                Console.WriteLine("Kod NEMA opravneni pro pristup k promenne prostredi PATH");
            }
        }
}

Při použití deklarativního způsobu použijeme atribut pro konkrétní typ oprávnění a specifikujeme, jakou akci chceme provést. K tomu nám slouží výčet SecurityAction. Takže pokud chceme oprávnění vyžádat, použijeme hodnotu výčtu Demand. Další upřesňující informace pro vyžádání oprávnění specifikujeme pomocí pojmenovaných parametrů.

[FileIOPermission(SecurityAction.Demand, PathDiscovery = "C:/")]
private static void DoFilePermDemand()
{
       Console.WriteLine("Pristup k disku z byl overen");
       //dalsi implementace metody..
}

Dočasné odepření přístupu ke zdroji

Vyžadování oprávnění není jediná operace, kterou jsme schopni v našem kódu provádět. Můžeme také zařídit, že dočasně odepřeme přístup k danému zdroji, takže i když bude volající kód podle konfigurace disponovat oprávněním pro přístup k tomuto zdroji, jeho požadavek o použití zdroje stejně skončí vyhozením výjimky. Za tímto účelem využijeme metody Deny, která se nachází na všech typech oprávnění, které implementují rozhraní IStackWalk. Po zavolání této metody, bude tedy jakýkoli pokus o přístup k danému zdroji v rámci aplikace odepřen.

public class DenyExample
{
        public static void TestDeny()
        {
            string path = @"C:\file.dll";
            //vytvoreni instance tridy zabezpeceni
            FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.Write, path);
            //docasne odepreni pristupu k souboru
            perm.Deny();
            StreamWriter writer = null;
            try
            {
                //tento pokus skonci vyhozenim vyjimky
                writer = new StreamWriter(path);
            }
            catch (SecurityException ex)
            {
                Console.WriteLine(ex);
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }

            //vratime docasne odepreni pristupu k souboru
            CodeAccessPermission.RevertDeny();

            try
            {
                //tento pokus bude jiz uspesny
                writer = new StreamWriter(path);
            }
            catch (SecurityException ex)
            {
                Console.WriteLine(ex);
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }
}

K tomu, abychom opět umožnili přístup k chráněnému zdroji musíme použít statickou metodu třídy CodeAccessPermission, kterou je metoda RevertDeny. Tato metoda vrátí zpět všechna odepření v rámci volání. Jak můžete vidět po spuštění příkladu, druhý pokus o použití souboru, který se děje po zavolání této metody je již úspěšný.

Pokud budeme chtít na úrovni určitého elementu programového kódu odepřít přístup k nějakému zdroji pomocí deklarativní bezpečnosti použijeme v atributu oprávnění SecurityAction.Deny.

[FileIOPermission(SecurityAction.Deny, AllLocalFiles = FileIOPermissionAccess.AllAccess)]
public static void TestDeclarativeDeny()
        {
            string path = @"C:\file.dll";
            StreamWriter writer = null;
            try
            {
                writer = new StreamWriter(path);
            }
            catch (SecurityException)
            {
                Console.WriteLine("Kod nema opravneni pro pristup k soubouru");
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
}

Dočasné povolení oprávnění

Podobně jako je možné dočasně odepřít přístup ke zdroji, je možné i přístup dočasně povolit. To znamená, že pokud volající kód disponuje určitým oprávněním, může toto oprávnění dočasně povolit, čímž zapříčiní, že i když kód, který jej volá, daným oprávněním nedisponuje, použití zdroje bude možné. Pro dočasné použití použijeme metodu Assert na instanci představující konkrétní oprávnění.

public class AssertExample
{

        public static void TestAssert()
        {
            FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.AllAccess, "C:/file.txt");
            //docasne odepreme pristup k souboru
            perm.Deny();
            FileWriter writer = new FileWriter();
            writer.WriteMessage();
        }
       
    }

    public class FileWriter
    {
        public void WriteMessage()
        {
            StreamWriter writer = null;
            FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.AllAccess, "C:/file.txt");
            //docasne povolime pristup k souboru
            perm.Assert();
            try
            {
                writer = new StreamWriter("C:/file.txt");
                writer.WriteLine("Nejaka zprava..");
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
            //zrusime docasne povoleni pro pristup k souboru
            CodeAccessPermission.RevertAssert();
        }
}

V příkladu je pomocí metody Deny nasimulováno, že volající kód nemá oprávnění pro přístup k danému souboru. Avšak v metodě WriteMessage třídy FileWriter, která je tímto kódem volána, je použita metoda Assert pro dočasné udělení oprávnění a přístup k souboru neskoční vyhozením bezpečnostní výjimky.

Po provedení operací nad daným zdrojem je potřeba uvést vše do původního stavu pomocí statické metody RevertAssert třídy CodeAccessPermission, jinak by po opuštění důvěryhodného kódu mohlo dojít k narušení bezpečnosti méně důvěryhodným kódem (to znamená, že by mohl používat zdroj na který nemá oprávnění). Obecně doporučuji být při využívání metody Assert velmi opatrný. V případě použití deklarativní bezpečnosti se pro dočasné udělení oprávnění použije SecurityAction.Assert v atributu oprávnění.

Příklady ke článku lze stáhnout zde.

Příště dále rozebereme programové použití CAS.

Témata článku: Software, Microsoft, Programování, Public, Catch, Kody, Nema, Nemo, Reflex

1 komentář

Nejnovější komentáře

  • gully, gully 7. 8. 2006 12:41:02
    Off-line verzi seriálu si můžete stáhnout z
reklama
Určitě si přečtěte

Vybíráte herní periferii nebo hardware? Pak zapomeňte na nálepku Gaming

Vybíráte herní periferii nebo hardware? Pak zapomeňte na nálepku Gaming

** Herní hardware se od toho běžného často liší jen vzhledem ** Při výběru stále nezapomínejte na základní parametry ** Poradíme jak vybrat herní hardware i periferie

20.  2.  2017 | Stanislav Janů | 36

10 nejhorších produktů v historii Microsoftu

10 nejhorších produktů v historii Microsoftu

20.  2.  2017 | Karel Javůrek | 141

AMD oficiálně představilo procesory Ryzen. Známe i jejich české ceny

AMD oficiálně představilo procesory Ryzen. Známe i jejich české ceny

** AMD uvedlo první tři procesory Ryzen 7 ** Všechny budou pracovat s osmi jádry a šestnácti vlákny ** Na pulty obchodů se dostanou už za týden

22.  2.  2017 | Stanislav Janů | 132

Pojďme programovat elektroniku: Žádný bastlíř se neobejde bez armády švábů

Pojďme programovat elektroniku: Žádný bastlíř se neobejde bez armády švábů

** Každý bastlíř se po čase neobjede bez armády švábů ** Dnes si některé z nich vyzkoušíme ** Třeba zázračný posuvný registr

19.  2.  2017 | Jakub Čížek | 40

EU se děsí Windows 10. Prý o nás vědí až příliš. Microsoft chystá změny

EU se děsí Windows 10. Prý o nás vědí až příliš. Microsoft chystá změny

** Evropští úředníci chtějí, aby byly Desítky transparentnější ** Microsoft od jara skutečně chystá změny ** Ochráncům soukromí to ale nestačí

21.  2.  2017 | Jakub Čížek | 218

Remix Singularity: Microsoft si na tom vylámal zuby. Jak dopadne Android?

Remix Singularity: Microsoft si na tom vylámal zuby. Jak dopadne Android?

** Microsoft do svých telefonů integroval desktopové prostředí ** Moc to ale nevyšlo, chyběl pořádný výkon ** Teď to zkoušejí ex-googleři s Remix Singularity

23.  2.  2017 | Jakub Čížek | 74


Aktuální číslo časopisu Computer

Supertéma o počítačové bezpečnosti

AMD Ryzen přichází

Velké testy kinoprojektorů a levných špuntových sluchátek

Příslušenství do USB-C

reklama
reklama