Hoofdstuk 1 (link), hoofdstuk 2 (link) en hoofdstuk 3 (link), nu tijd voor het 4e hoofdstuk, het implementeren van Azure security. We gaan het over de 5 dimensies van informatie-beveiliging: integrity, availability, confidentiality, authorization en no-repudiation.
Authenticatie
Als een gebruiker toegang wil hebben moet hij/zij kunnen aantonen wie hij/zij is. Dat kan met iets dat de persoon heeft en iets wat die persoon heeft, multifactor-authenticatie. Azure biedt verschillende mogelijkheden, die gaan we hier behandelen;
Authenticatie met behulp van certificaten, forms-gebaseerde authenticatie of tokens.
Je hebt natuurlijk de form-based authenticatie. Door een gebruikersnaam en wachtwoord in te vullen en naar de server te sturen wordt gevalideerd of deze gegevens kloppen. Zo ja, dan krijg je een cookie terug, waardoor in de opvolgende aanvragen duidelijk is welke user deze actie uitvoert. Niet veilig via HTTP (omdat het dan plain-text is), dus altijd via HTTPS.
Je hebt te maken met drie elementen:
- de formulieren. Niet alleen om je aan te melden, maar ook voor het resetten van je wachtwoord. En mogelijk voor het aanvragen van een account.
- credential storage, de gegevens moeten "ergens" opgeslagen worden.
- credential management, een wachtwoord wordt niet als "plain-text" opgeslagen, het hashen, het verwerken van password-resets en het verwerken van aanmeldingen wordt door deze component uitgevoerd.
Bij het standaard voorbeeld wat in het boek gegeven wordt, wordt gebruik gemaakt van ASP.NET Identity. Ook dit bestaat uit een aantal onderdelen:
- users, de gebruikers. Username, e-mail, gehashte wachtwoorden, security-stamp voor validatie van de gegevens.
- user claims, bepaalde extra eigenschappen van de user worden hierin op geslagen.
- user logins, informatie over externe login-partijen, zoals Twitter, Facebook, Google.
- roles, bijhouden van de gebruikersrollen, Admin, User.
De data is basic, e-mailadres en wachtwoord. Het boek geeft wat aanvullingen, bijvoorbeeld profielinformatie aanpassen in VS 2013 templates: link.
En bij ASP.NET Core projecten: link.
Het boek benoemt vervolgens de middleware die de authenticatie kan uitvoeren, OWIN (Open Web INterface). Het is een open-source specificatie die de code loskoppelt van de webserver. De code plaats je dus ook niet in de global.asax, maar in de Startup class. De implementatie die Microsoft uitgevoerd heeft wordt project Katana genoemd en is hier verder te bekijken: link.
Er worden 2 bestanden genoemd, Startup.Auth.cs, waar je de configuratie inregelt.
// koppeling met de database:
app.CreatePerOwinContext(ApplicationDbContext.Create);
// UserManager aanmaken
app.CreatePerOwinContext (ApplicationUserManager.Create);
// SignInManager aanmaken
app.CreatePerOwinContext (ApplicationSignInManager.Create);
De ApplicationUserManager regelt alles met aanmaken accounts, verwijderen accounts.
De UserManager zelf slaat geen data op, het levert de data aan bij de UserStore, deze class gebruikt de IdentityDbContext om de data op te slaan. Hetzelfde geldt voor de ApplicationSignInManager die overerft van de SignInManager.
Het andere bestand is IdentityConfig.cs. Hier geef je onder andere aan hoe complex een wachtwoord moet zijn.
Het gebruik van Form-based authenticatie heeft zijn nadelen. Zo werkt het niet altijd lekker op mobiel. Houdt je server een sessie open houdt voor de geauthenticeerde clients, waardoor de site minder schaalbaar wordt. Er is een alternatief, token-based authenticatie. Dat mechanisme is bedoeld voor situaties waarbij er hoge schaalbaarheid nodig is en mogelijk cookies niet ondersteund worden. Een niet geauthenticeerde client gaat naar de site, gaat vervolgens naar de inlogpagina, logt in met geldige gegevens en krijgt een JWT token terug. De client moet dit opslaan en meesturen bij volgende requests. JSON web token of JWT is de meest gebruikte variant.
Dit token bestaat uit:
- header, hierin geef je aan welk algoritme gebruikt is voor het token
- body of "payload", informatie over het token en het doel van het token. Het bevat standaard velden of claims die voldoen aan RFC 7519 en andere eigen velden die nodig zijn.
- cryptografische handtekening, een tekstwaarde waarmee wordt gevalideerd dat de data niet corrupt is of door iemand anders aangepast is.
Met tokens kun je het beheer uit handen geven, laat Facebook, Google, Twitter de data bijhouden. Het boek geeft het voorbeeld van Google+, ga naar link link en richt daar een applicatie in. In je .NET project, activeer deze code:
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { ClientId = "", ClientSecret = "" });
Google geeft aan dat ze hiermee gaan stoppen en met een andere SDK aan de slag gaan, kijken of dat dan (nog) werkt: l link. Met onderstaande setting geef je aan dat cookies van externe partijen geldig zijn: app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); Er wordt hier nog steeds met cookies gewerkt. Een alternatief is het werken met certificaten. De server vraag dan aan een client om een geldig certificaat aan te leveren. Dit heeft meer voeten in aarde (op de server moet je een private-key infrastructuur opbouwen (PKI) en je moet zorgen dat de clients op een veilige manier in het bezig kunnen komen van het client certificaat. Op deze pagina kun je er meer over lezen: l link.
Dan is er Azure Active Directory (Azure AD). Bij veel bedrijven wordt al gebruik gemaakt van Microsoft Active Directory Domain Services (AD DS). Het is niet dezelfde service, ze bieden verschillende diensten en Azure is cloud gericht. Waarbij AD DS meer "on premise" gericht is. Windows authenticatie is wat je met AD DS doet, via Kerberos en NTLM protocollen. Deze zijn niet echt geschikt voor "de cloud", dus je moet naar alternatieven zoeken. Vaak hebben bedrijven beide systemen en zorgen ervoor dat als er een user aangemaakt of aangepast wordt in AD DS, dit ook doorgestuurd wordt naar het Azure AD systeem. Hier zijn 2 methodes voor, Azure AD Connect of Active Directory Federation Services (AD FS): link. Als je een desktop of mobiele applicatie bouwt die Azure AD authenticatie nodig heeft en waarbij je client-omgeving in een AD DS domein zit, daar kun je de Microsoft Authentication Library for .NET gebruiken (MSAL.NET). Hierbij moet via AD FS de connectie gemaakt zijn en de user zowel in de on-premise als in de Azure AD aanwezig zijn. Broncode is te vinden op Github: link.
Meer informatie en bronnen voor authenticatie code-bibliotheken is hier te vinden: lin link.
Meer uitleg over de Active Directory Federation Services is hier te vinden: link.
Voordeel van het gebruik van Azure AD en niet een eigen systeem bouwen is dat je veel features direct beschikbaar hebt. Bijvoorbeeld MFA, multi-factor-authentication. Met de authenticator mobile app heb je een extra wall-of-defense. Je kunt MFA instellen dat deze alleen bij bepaalde gebruikers of applicaties gebruikt wordt. Op deze pagina kun je daar meer over lezen: link.
Implementeer OAuth2 authenticatie
We konden al via Google, Facebook, Twitter een OAuth2-flow doorlopen. Maar het boek toont ook het voorbeeld om zelf zo'n systeem te bouwen. De client doet eerst een authorization request naar de resource owner. Indien OK geeft deze een authorization grant terug. Deze stuurt de client naar de authorization server. Indien OK geeft deze een access token terug. Dit token stuurt de client naar de resource server. Indien OK stuurt deze de resource/afgeschermde informatie naar de client. De flow hiervoor is in onderstaande RFC uitgewerkt: link. Het boek verwijst voor meer informatie naar deze URL, maar daar is geen informatie te vinden. Wel staat er dat .NET core haar eigen implementatie heeft: link.
Implementeer Managed Service Identity (MSI)/Service Principal authenticatie
Bij veel zaken moet je credentials "ergens" opslaan. Een connectiestring (maar die staat dan ook op de pc van de developer, in source-control). En je kunt Key Vault gebruiken, maar die connectiegegevens moeten ook ergens opgeslagen worden. Azure Active Directory biedt Managed Identities for Azure resources (dat was vroeger Managed Service Identity). Elke dienst die Azure AD ondersteunt heeft daardoor geen losse credentials meer nodig.
Je werkt dan met 2 verschillende types:
- system assigned managed identities, als je een VM aanmaakt of Azure Data Lake Store, dan maakt Azure ook een identity aan.
- user assigned managed identities, je kunt in de Azure AD zelf je gebruikers aanmaken en ze aan service instanties koppelen.
Je werkt met 3 items:
- Client ID, unieke ID door Azure AD gegenereerd, de associatie van de application en de service principal tijdens initiele provisioning.
- Principal ID, ID van de service principal die gekoppeld is met de managed identity. Ze zijn gekoppeld, maar verschillend. De principal is het object wat je gebruikt om rol-gebaseerde toegang aan een Azure resource toe te wijzen.
- Azure Instance Metadata Service (IMDS). Binnen een VM kun je managed identities met een OAuth token laten werken. IMDS is een REST-endpoint dat je binnen de VM via een intern IP-adres kunt bereiken.
Implementeer toegangscontrole
Na de authenticatie ga je kijken wat een user mag/kan doen. Dat kan rol-gebaseerd zijn, Role-Based Access Control, maar ook op basis van de informatie die de gebruiker aanlevert, Claim-Based Access Control.
Claim-based
Een geauthenticeerde entiteit bevat allemaal eigenschappen, key-value gebaseerd. Dat kan een geboortedatum zijn, e-mailadres. Zo zou je toegang kunnen verlenen op een deel van je applicatie als de gebruiker 18 jaar of ouder is, dat noem je een policy. In het controller-deel voeg je een AuthorizeAttribute toe. Met deze code-snippet zorg je dat claims gebruikt kunnen worden:
.AddAzureAD:
services.AddAuthorization(options => { options.AddPolicy("RequireMFA", policy => policy. RequireClaim("http://schemas.microsoft.com/claims/ authnmethodsreferences", "mfa")); });
Door voor de class in de controller onderstaand statement te plaatsen, dwing je af dat alleen als aan die policy voldaan wordt de code uitgevoerd wordt:
[Authorize(Policy = "RequireMFA")]
Meer informatie over claims: link. Meer informatie over policies: link.
Role-based
Het boek gebruikt dit project als voorbeeld: github-link. Hierdoor kan boven de functie aangegeven worden welke rol(len) deze mogen uitvoeren:
[Authorize(Roles = AppRoles.UserReaders )]
Shared Access Signatures
Als je externe diensten toegang wilt geven, dan werken die claims en rollen niet. Daarvoor heb je de Shared Access Signatures (SAS). Als je een SAS token maakt geef je aan welke blobs, files, queues, tables beschikbaar zijn en welke acties de gebruiker daarop kan/mag uitvoeren.
Je kunt een SAS op verschillende levels aanmaken:
- service: als je hier een SAS token aanmaakt zijn alle contains en blob-opslag beschikbaar
- container: binnen een storage service alleen toegang tot de elementen binnen de container
- element: alleen beschikbaar voor blobs en files
Implementeer veilige data-oplossingen
Authenticatie en autorisatie is niet voldoende, als de data via een omweg publiekelijk toegankelijk is heb je alsnog een groot probleem. Zorg dat data geëncrypt wordt, tijdens opslag en tijdens uitwisseling van data.
- Stuur de data over SSL, nooit plain HTTP
- Bij het SAS token kun je aangeven dat HTTPS afgedwongen moet worden
- SMB 3.0, SMB is voor toegang tot bestanden in Azure File Storage, Windows 2012 of de nieuwe Azure Virtuele Machines. Encryptie staat standaard aan. Dan moet je trouwens wel de encryptie op je file-shares actief maken.
- RDP, hiermee kun je VM's bereiken, protocol gebruikt TLS.
- SSH, hiermee kun je VM's bereiken, met public/private key zorg je dat je geen username/password nodig hebt.
- VPN, hiermee zorg je voor een veilige connectie.
Opslag van data kan op verschillende manieren geëncrypt worden:
- Service-Managed keys, Azure versleutelt de boel server-side. Azure Resource Provider zorgt voor encryptie en decryptie.
- Op basis van eigen keys in de Azure Vault, de klant levert en beheert de encryptie-keys, Azure Resource Provider zorgt nog steeds voor encryptie en decryptie.
- De klant kan een eigen stuk hardware hebben die de encryptie-keys aanleveren. Niet elke Azure service ondersteunt dit. Ook hier, Azure Resource Provider zorgt nog steeds voor encryptie en decryptie.
- En de enige optie waarbij de data door de klant geëncrypt wordt en vervolgens geupload wordt. Bij downloaden moet de klant dit zelf ook weer decrypten.
Meer informatie is hier te vinden, over opslag: link en algemeen: link.
Het boek toont het voorbeeld hoe met de API van Azure Key Vault gecommuniceerd kan worden voor het doorvoeren van aanpassingen. Hierbij wordt dit code-snippet gebruikt:
var azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVault = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureService TokenProvider.KeyVaultTokenCallback));
Meer informatie is hier te vinden: link.