# Programmeren in ASP.NET/Beveiliging
## Inleiding

Beveiliging bestaat uit altijd uit twee delen:
* Authenticatie: Wie is de gebruiker?
* Autorisatie: Wat mag deze gebruiker doen?
Authenticatie gebeurt dikwijls op basis van een gebruikersnaam en een wachtwoord, maar tegenwoordig zijn er nog andere mogelijkheden, zoals met een elektronische ID-kaart (eID) of zelfs met vingerafdrukken.
Standaard gebeurt autorisatie op basis van gebruikersrechten van bestanden. Het nadeel hiervan is dat als je gebruikers wilt kunnen onderscheiden, je voor iedere gebruiker een Windows-gebruikersaccount moet aanmaken. Op een Intranet kan dit juist handig zijn, maar op een website met veel bezoekers is dat moeilijk of zelfs onmogelijk.

## IIS-beveiliging

IIS-beveiliging heeft niets met ASP.NET te maken. Dit betekent dat deze beveiliging geldt voor alle bestanden: aspx, maar ook htm, html, jpg, gif, css, enzoverder.
IIS-beveiliging is een goede optie voor een intranet, maar niet voor de beveiliging van sites op het Internet, omdat alleen de provider de instellingen kan veranderen.
De instellingen kan je wijzigen op deze manier:
* Start - Settings - Control Panel - Administrative Tools - Internet Services Manager.
* Blader naar Default Web Site.
* Selecteer deze tak en kies Properties, dan Directory Security.
* Klik op Edit.

### Zonder anonieme toegang

Standaard staat anonieme toegang aan. Dit betekent dat iedereen bestanden mag opvragen zonder in te loggen.
Zet Anonymous Access en Windows Integrated Authentication uit. Maak een pagina test.htm in wwwroot, en vraag in de browser http://localhost/test.htm op. Je wordt gevraagd om in te loggen.
Er zijn drie soorten authenticatie in IIS:

#### Basic

    de gebruikers moeten een Windows gebruikersnaam en wachtwoord geven om toegang te krijgen. Het wachtwoord wordt verzonden als gewone tekst, waardoor deze methode onveilig is op het internet (als iemand de lijn zou aftappen of "sniffen")

#### Digest

    hier wordt het wachtwoord versleuteld verzonden. Dit werkt alleen als alle gebruikers Internet Explorer 5 of hoger gebruiken, en als de wachtwoorden bewaard worden in Active Directory op een Windows-server.

#### Integrated

    wachtwoorden worden helemaal niet over het netwerk verstuurd, maar er wordt een speciaal protocol gebruikt om in te loggen. Dit vereist Internet Explorer 3.01 of hoger.

### Met anonieme toegang en bestandsbeveiliging

Zet nu anonieme toegang weer aan. Merk op dat er voor anonieme toegang een speciale gebruikersidentiteit wordt gebruikt met de naam IUSR_COMPUTERNAAM.
Maak een tweede bestand test2.htm, en stel hiervan via Windows Explorer de beveiliging in zodat alleen jij dit bestand mag lezen. Open een nieuw browservenster. Je kan nu zonder problemen test.htm opvragen, maar voor test2.htm moet je inloggen.

## ASP.NET-beveiliging

Het nadeel van IIS-beveiliging is dat je daarvoor toegang tot de server moet hebben. Met behulp van ASP.NET kan je je pagina's beveiligen via een eenvoudig configuratiebestand dat je alleen naar de server moet kopiëren. Het nadeel is wel dat deze beveiliging alleen voor ASP.NET-bestanden (aspx, asmx, ascx) werkt.
ASP.NET biedt in totaal 4 mogelijkheden ("modes"):

### None

    geen beveiliging (anders gezegd: laat IIS de beveiliging doen). Dit is de standaard instelling

### Windows

    Windows-beveiliging, waarbij de gebruiker via een popup-scherm inlogt, en ASP.NET instelt welke folders beveiligd zijn. Deze beveiliging is alleen geschikt voor een Intranet, niet voor een publieke site

### Forms

    inloggen gebeurt met een HTML-formulier

### Passport

    maakt gebruik van .NET Passport en wordt hier niet besproken
De instellingen van de beveiliging gebeuren in het configuratiebestand web.config. Dit betekent dat je per folder eventueel andere rechten kan gebruiken. De mode (None, Windows, Forms of Passport) geldt wel voor alle folders van de applicatie, en kan daarom alleen in web.config van de rootfolder ingesteld worden.
Opmerking Om dit soort beveiliging mogelijk te maken, moet het bestand web.config toegankelijk zijn voor eender wie er inlogt (in feite moet het al toegankelijk zijn nog voor ze ingelogd zijn). Zet dus nooit bestandsbeveiliging op web.config.

### ASP.NET Windows-beveiliging gebruiken

Deze beveiliging is dikwijls ideaal voor een Intranet, omdat je de gebruikersdatabank kan overnemen van het gebruikersdomein op het netwerk.
Maak een bestand web.config aan in wwwroot. Verander het "authentication"-element als volgt:
In het mode-attribuut van het authentication-element geef je op welke manier van beveiligen je wil gebruiken, in dit geval dus Windows.

### Authorisatie

Eenmaal de authenticatiemethode ingesteld, is de volgende stap: aangeven welke gebruikers wat mogen. Dit doe je met het authorization-element in web.config. Alle instellingen die je daarin doet zijn van toepassing op de map waarin het betreffende web.config-bestand staat en alle mappen daaronder, tenzij een van die mappen een eigen web.config bevat met daarin afwijkende autorisatiegegevens (of tenzij je "location"-elementen toevoegt aan web.config) De autorisatiegegevens in web.config zien er bijvoorbeeld als volgt uit:
De allow-elementen geven aan welke gebruikers toegang hebben tot de map, in dit geval michel van het domein onsdomein en alle leden van de groep administrators. De deny-elementen geven aan welke gebruikers geen toegang hebben.
Voor afzonderlijke gebruikers zet je allow/deny users, voor gebruikersgroepen zet je allow/deny roles.
Test deze beveiliging uit met je eigen naam.
Zeer belangrijk: ASP.NET doorloopt alle elementen, van boven naar beneden, tot er een "match" gevonden wordt voor de aangelogde gebruiker, en die instelling wordt dan toegepast. Een sterretje geeft daarbij alle ingelogde gebruikers aan. Een vraagteken ? geeft alle niet ingelogde ("anonieme") gebruikers aan. Als je
als eerste zet, dan krijgen alle gebruikers automatisch de eerste keer een inlogscherm te zien. De volgende regels bepalen dat iedereen (die gekend is op de server of het domein) toegang heeft, behalve anonieme gebruikers (anders gezegd: je moet in dit geval gewoon inloggen om toegang te krijgen):

### Forms-beveiliging in ASP.NET

Bij Forms-beveiliging kijkt ASP.NET of de gebruiker toegang mag hebben tot een bepaalde pagina. Heeft de gebruiker niet de vereiste toegangsrechten, of is de gebruiker nog niet ingelogd, dan wordt de gebruiker verwezen naar een login-pagina. Dit is een pagina waar de gebruiker meestal zijn of haar naam kan invullen, samen met een wachtwoord.
Als de gebruiker vervolgens inlogt en de juiste rechten heeft, dan wordt de gebruiker terugverwezen naar de pagina die hij/zij oorspronkelijk had opgevraagd. Dit gebeurt allemaal automatisch. Het enige wat je moet programmeren is de login-pagina en het instellen van de rechten voor de verschillende gebruikers. Achter de schermen wordt alles gecontroleerd met behulp van een cookie die na een bepaalde tijd verloopt.
Je stelt Forms-beveiliging in via het authentication element in web.config, zoals hieronder getoond.
Het forms-element bepaalt vervolgens de instellingen van de Forms-beveiliging. In de tabel hieronder vind je de verschillende mogelijke attributen.
Tabel: Eigenschappen voor Forms-beveiliging
| Eigenschap | Omschrijving |
| name | Naam van de cookie die naar de webbrowser van de gebruiker wordt gestuurd. |
| loginUrl | URL naar de loginpagina. Dit moet een URL zijn binnen de website. De defaultwaarde is "login.aspx" |
| path | Pad binnen de website waarvoor de beveiligingscookie geldt. Dit is alleen van toepassing als je meerdere applicaties op dezelfde server hebt draaien. |
| protection | Manier waarop de cookie wordt beveiligd tegen kwaadwilligen. Mogelijke waardes zijn: All (standaard) voor de sterkste (en aanbevolen) beveiliging None voor geen beveiliging (niet aanbevolen, behalve voor personalisatie) Encryption voor versleutelde gegevens ·* Validation voor het controleren van de waardes in de cookie. Noot: All gebruikt zowel Encryption als Validation. |
| timeout | Aantal minuten dat de cookie geldig is. |
De vraag is nu alleen nog: hoe laat je gebruikers inloggen en op basis van welke logingegevens? Je hebt daarbij de keuze zelf de logingegevens op te slaan, bijvoorbeeld in een database, en deze te controleren.

### Inloggen met Forms-authenticatie

Wat je ook doet, je moet een formulier maken om in te loggen. De code voor het daadwerkelijke inloggen hangt af van de manier waarop je de gebruikersnamen en wachtwoorden wilt opslaan. In ieder geval moet je wel de System.Web.Security-naamruimte importeren.
De onderstaande code laat zien hoe je in kunt loggen op basis van een eigen opslag, met behulp van de methode FormsAuthentication.RedirectFromLoginPage. Deze methode heeft 2 parameters: de eerste is de naam van de gebruiker, en de tweede is een boolean. Indien True dan wordt een permanente cookie geplaatst, waardoor je de volgende keer vanzelf weer ingelogd bent. Indien False, dan ben je maar ingelogd zolang de huidige sessie duurt.
login2.aspx
In het voorbeeld hierboven wordt de gebruikersnaam en het wachtwoord vergeleken met waardes die direct in de paginacode staan. Je kan dit vervangen door een controle die je eigen methode gebruikt, bijvoorbeeld op basis van een databank.

### Beveiliging van virtuele folders

Als je een subfolder "website1" hebt binnen wwwroot, en je probeert met behulp van een web.config in die folder de authenticatiemode in te stellen, dan krijg je een foutmelding: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level.
De authenticatiemode kan alleen in de rootfolder ingesteld worden, omdat die instelling voor een ganse applicatie geldt.
Als je voor "website1" een virtuele folder aanmaakt die ingesteld staat als een applicatie (dit is de standaard instelling), dan kan je de beveiliging weer instellen.

### Beveiliging van subfolders

Dikwijls heb je binnen een website één of meerdere subfolders met beperkte toegang (zogenaamde "member" of "admin" zones). Om deze een andere beveiliging te geven dan de root gebruik je het "location"-element in het basis-web.config bestand.
In het voorbeeld hieronder krijgt iedereen toegang tot de bestanden, maar binnen de folder "admin" krijgt alleen de beheerder toegang.
Het voorbeeld hieronder gebruikt Forms-authentication. Je moet alleen inloggen voor de folder "admin". Als je op een of andere manier in die folder terechtkomt, zal je automatisch de inlogpagina krijgen.
In het location-element mag je zowel folders als bestanden opgeven in het path-attribuut. Je mag meerdere location-elementen in web.config zetten. Vergeet bij subfolders en bestanden niet als laatste <deny users="*" /> te zetten, anders worden voor alle andere gebruikers de regels van de hoofdfolder toegepast (en krijgen ze dus wel toegang in dit geval).
Dit mag alleen in de rootfolder staan, zoals reeds gezegd:
Je kan ook in elke folder een aparte web.config zetten, en die mogen elk hun eigen <authorization>-instellingen hebben, maar geen <authentication>-instelling.

### Impersonation

Soms moet je applicatie zich als een bepaalde gebruiker voordoen om bepaalde zaken te kunnen doen op een website (bijvoorbeeld SQL Server gebruiken, of een proxyserver gebruiken). Dit noemt men impersonation. Impersonation werkt alleen bij Windows-authentication. Standaard is er geen impersonation. Je kan dit ook expliciet instellen in web.config met dit element:
Dit betekent dat ASP.NET altijd draait onder zijn eigen account, en dit is de account met gebruikersnaam ASPNET (Windows 2000/XP) of NETWORK SERVICE (Windows 2003). Deze gebruiker wordt automatisch aangemaakt op de server op het moment dat ASP.NET geïnstalleerd wordt. Deze gebruiker heeft standaard weinig rechten (bijvoorbeeld geen toegang tot "My Documents").
Als jouw webpagina's bepaalde code uitvoeren waarvoor meer rechten nodig zijn, dan kan je impersonation gebruiken:
In dit geval zal ASP.NET de gebruikersidentiteit overnemen die het krijgt van IIS. Dit betekent dat je bij anonieme toegang in IIS de gebruiker IUSR_COMPUTERNAAM gebruikt. Bij niet-anonieme toegang wordt de identiteit gebruikt waarmee ingelogd werd. Als je dus inlogt als "Jan", dan zal de applicatie voor alles wat ze moet doen de identiteit van Jan gebruiken.
Je kan een bepaalde gebruikersnaam opgeven om te gebruiken voor alle authenticatieverzoeken:
Bedenk wel dat het wachtwoord dan zichtbaar is voor iedereen die web.config kan lezen.
Om te controleren welke identiteit gebruikt wordt kan je dit blok ergens in de pagina zetten:

## Samenvatting
### Login-controls

In ASP.NET 1.x vergt de Forms-beveiliging redelijk wat werk. Je moet een gegevensbron met gebruikers opzetten, een loginprocedure schrijven, en een login-formulier maken. Verder kun je ook nog denken aan functionaliteit waarmee gebruikers zich kunnen registeren, en een mogelijkheid om een vergeten wachtwoord op te vragen. Wil je dan ook nog dat pagina’s er verschillend uitzien voor aangemelde gebruikers en niet-aangemelde gebruikers, en voor verschillende rollen, dan ben je echt wel een paar dagen zoet om het allemaal voor elkaar te krijgen.
ASP.NET 2.0 bevat een verzameling beveiligingscontrols:
| Control | Omschrijving |
| Login | Laat een formulier zien waarin gebruikers hun gebruikersnaam en wachtwoord invoeren. Ook validatie van de gebruiker |
| LoginName | Laat de naam van de aangemelde gebruiker zien. |
| LoginStatus | Laat zien of de huidige gebruiker is aangemeld, en geeft een link weer die de aangemelde gebruiker afmeldt. |
| ChangePassword | Laat een formulier zien waarmee gebruikers hun wachtwoord kunnen aanpassen. |
| CreateUserWizard | Laat een serie formulieren zien waarmee een gebruiker aangemaakt wordt. |
| PasswordRecovery | Laat een formulier zien waarmee gebruikers hun wachtwoord (of een nieuw wachtwoord) naar hun e-mailadres kunnen laten sturen. |
| LoginView | Laat een weergave zien die afhankelijk is van of een gebruiker aangemeld is of niet, en eventueel op basis van de rol van de gebruiker. |
De controls kunnen vrijwel op alle manieren aangepast worden als het om de opmaak en teksten gaat. De meeste controls bieden bovendien de mogelijkheid om de opmaak te verzorgen via een verzameling templates, zodat je alles zelf kan aanpassen. Is dat nog niet genoeg, dan kun je altijd nog de nodige code zelf toevoegen.

## Provider instellen

Om deze controls te kunnen gebruiken, moet je eerst een zogenaamde Membership Provider kiezen. Dit doe je als volgt:
* Controleer of SQL Server 2005 geïnstalleerd is op de server.
* In het Visual Studio-menu, kies Website – ASP.NET configuration. Er opent een webpagina voor de configuratie van je website.
* Klik op de klep "Provider".
* Kies "Select a single provider for all site management data".
Er is nu een SQL Server-Express-databank AspNetDB.MDF aangemaakt in de subfolder App_Data. Deze databank bevat een aantal tabellen om gebruikers, roles en dergelijke te beheren.
ASP.NET 2.0 bevat standaard alleen een provider voor SQL Server 2005, maar andere providers en uitbreidingen zijn mogelijk.
De login-controls worden vanaf nu automatisch gekoppeld aan deze provider.
Een provider zoals deze kan verder nog gebruikt worden voor personalisatie.
Via de configuratie-website kan je eventueel al gebruikers toevoegen met hun naam en wachtwoord, maar dat kan ook met de login-controls zelf.

## Login-controls gebruiken

Indien dit nog niet gebeurd zou zijn, wijzig dan web.config als volgt:
Vervang de regel
door de regel:
Maak nu eerst een nieuwe master-pagina "login.master".
Sleep op de master een LoginStatus-control en een LoginName-control. De LoginStatus-control toont of de gebruiker ingelogd is of niet en de LoginName-control toont de naam van de ingelogde gebruiker. Door deze controls in de master te zetten komen ze automatisch op elke pagina terug.
login.master
Daarna maak je een startpagina, met alleen een titel:
loginhome.aspx
Als je de pagina opvraagt, zie je een link "login". De naam wordt nog niet getoond, want er is nog niemand ingelogd.
Als je op de link klikt, kom je op pagina "login.aspx". In web.config kan je eventueel een andere pagina instellen.
Nu maak je dus de login-pagina "login.aspx". Het enige wat je moet doen, is er een Login-control op slepen, en de CreateUserUrl en CreateUserText property's instellen.
login.aspx
Merk op dat de Login-control een aankruisvak "Remember me" toont. Door deze aan te vinken en daarna met succes in te loggen, wordt een blijvende cookie aangemaakt (50 jaar geldig) op de machine van de gebruiker. Deze optie kan je uitschakelen door de DisplayRememberMe en de RememberMeSet property's van de login-control op false te zetten.
Ten slotte maak je nog de CreateUser.aspx-pagina. Deze bevat alleen een CreateUserWizard-control. De ContinueDestinationPageUrl-property stel je best in zodat je weer op de home-pagina terecht komt.
createuser.aspx
Open nu de pagina, en maak een account aan.
Let op: het wachtwoord moet minstens 8 tekens bevatten, en daarin moet minstens 1 niet-alfanumeriek teken zitten.
Als de gebruiker een account aanmaakt, dan wordt die standaard bewaard in de SQLExpress-databank AspNetDB.MDF in de folder App_Data.
Opmerking Controleer of dit ook werkt onder IIS! Als je een foutmelding krijgt Unable to open the physical file "C:\Inetpub\website\App_Data\aspnetdb.mdf"., kan het zijn dat je op de folder App_Data de beveiliging moet wijzigen en (schrijf)toegang moet geven aan de gebruiker ASPNET.

## Andere inhoud tonen voor ingelogde gebruikers

Dikwijls wil je extra informatie of menu-onderdelen tonen als iemand ingelogd is. Dit kan met de LoginView-control:
loginhome2.aspx
Merk op dat er twee templates zijn: het LoggedInTemplate, en het AnonymousTemplate. Beiden bevatten aangepaste inhoud. In het LoggedInTemplate wordt hier ook nog de ChangePassword-control getoond.
Ook sitemaps hebben de mogelijkheid zich aan te passen aan de ingelogde gebruiker. Je moet daarvoor ook nog de optie securityTrimmingEnabled op True zetten in web.config op de volgende manier:
Automatisch krijgen gebruikers nu in het menu alleen de links te zien naar pagina's waar ze volgens web.config toegang toe hebben.

## Web site administration tool

Met deze tool kan je ook gebruikers aanmaken en beheren.
Je kan ze openen in Visual Web Developer via het menu Website – ASP.NET configuration of rechtsklikken in de Solution Explorer.

### Oefeningen

* Maak een website met 1 pagina in de rootfolder. Maak een subfolder "beheer" met ook 1 pagina. Stel de beveiliging met Windows-authentication zo in dat alleen de gebruiker "Administrator" de tweede pagina kan openen. Zorg dat deze site ook met IIS werkt (gebruik http://localhost in plaats van http://localhost:1234.
* Zelfde oefening, maar gebruik nu Forms-authentication.