Windows Azure + WIF + Access Control (ACS)

Als je gebruik gaat maken van de Access Control Service (ACS) op het Windows Azure platform, dan zijn er voldoende websites te vinden met een keurig stappenplan. Bijvoorbeeld hier. Hoewel er behoorlijk geconfigureerd moet worden, zowel in de applicatie als op de ACS website, is het goed te doen.

Als je vervolgens de gebouwde Windows Azure applicatie ook daadwerkelijk in de Cloud gaat laten draaien zijn er een aantal aha momenten. Hieronder een opsomming.

Het is wel handig om de website als SSL te maken.

1) De Windows Identity Foundation (WIF) runtime.

Op de standaard Windows Azure instances is de WIF runtime niet aanwezig. Uit verschillende discussie die ik gevolgd heb en eigen ervaring, blijkt dat een simpel ‘copy local’ van de WIF assembly (Windows.Identity.dll) niet voldoende. Je zult echt de WIF runtime moeten mee installeren met de installatie van de Windows Azure web applicatie.

Dat is relatief eenvoudig. Met behulp van het startup task mechanisme van Windows Azure kun je een batch file af starten en daarmee de runtime installeren. Deze runtime is te downloaden van hier. Er is zowel een x86 als x64 versie beschikbaar. De x64 heb je nodig voor het deployen naar Windows Azure. Afhankelijk van de gekozen OS Family (Windows 2008 of Windows 2008 R2) heb je de 6.0 of de 6.1 nodig. Ontwikkel je lokaal op Windows 7 of Windows 2008 R2 dan heb je ook 6.1 nodig.

In de ServiceDefinition.csdef van de WebRole voeg je het volgende stuk toe.  

   1:  <Startup>
   2:    <Task commandLine="startup.cmd" 
   3:               executionContext="elevated" 
   4:               taskType="simple">   
   5:    </Task>
   6:  </Startup>

Aan het webproject voeg je dan een file met de naam startup.cmd toe. Het makkelijkst is dat om in de root te doen. Anders moet je in de stap hierboven ook het path aangeven.

De startup.cmd bevat dan:
 

   1:  REM WIF assembly 
   2:  sc config wuauserv start= demand 
   3:  wusa.exe "%~dp0Windows6.1-KB974405-x64.msu" /quiet /norestart
   4:  rem wusa.exe "%~dp0Windows6.0-KB974405-x64.msu" /quiet /norestart 
   5:  sc config wuauserv start= disabled

Bij het deployen van de applicatie wordt in een van de stappen ook de startup task uitgevoerd.

2) Multiple instances

Zoals bekend moet je op Windows Azure om aan de SLA te voldoen in elk geval 2 instanties van je Role starten. Van Windows Azure ACS krijg je een cookie. Deze cookie wordt geencryptd en gedecryptd.

Deze versleuteling vindt plaats met de machine-sleutel van de instantie waar je zat. Maar op de andere instantie is de machine-sleutel natuurlijk anders en dan kan het cookie niet gelezen worden door een andere instantie.

De oplossing is dan ook vrij simpel, zorg ervoor dat de versleuteling plaats vind met voor alle machines een gelijke sleutel. Ik heb voor mijn domein een SSL certificaat gekocht en deze kan ik daar mooi voor gebruiken. Om dit goed te laten verlopen moet je in de Global.asax.cs de FederatedAuthentication.ServiceConfigurationCreated methode toevoegen.

   1:  protected void Application_Start()   
   2:  {   
   3:      AreaRegistration.RegisterAllAreas();   
   4:  
   5:      FederatedAuthentication.ServiceConfigurationCreated 
   6:             += OnServiceConfigurationCreated;   
   7:  }   
   8:   
   9:  void OnServiceConfigurationCreated(object sender, 
  10:                        ServiceConfigurationCreatedEventArgs e)   
  11:  {  
  12:      // Use the <serviceCertificate> to protect the cookies 
  13:      // that are sent to the client.  
  14:      // so multiple roles do the same.  
  15:      if (e.ServiceConfiguration.ServiceCertificate == null)  
  16:         return;  
  17:   
  18:      Trace.WriteLine("ServiceCertif: ", 
  19:                 e.ServiceConfiguration.ServiceCertificate.Thumbprint);  
  20:      List<CookieTransform> sessionTransforms =  
  21:          new List<CookieTransform>(  
  22:              new CookieTransform[] {  
  23:                  new DeflateCookieTransform(),
  24:                  new RsaEncryptionCookieTransform
  25:                         (e.ServiceConfiguration.ServiceCertificate),  
  26:                  new RsaSignatureCookieTransform
  27:                         (e.ServiceConfiguration.ServiceCertificate)   
  28:              }  
  29:          );  
  30:   
  31:      SessionSecurityTokenHandler sessionHandler =   
  32:         new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());  
  33:   
  34:      e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(
  35:                 sessionHandler
  36:      );  
  37:  }

3) Realm

Op mijn demo site zijn alle pagina’s zichtbaar zonder in te loggen, maar mag je secret page pas benaderen na inloggen. In de default situatie na het doorlopen van de wizard zullen alle pagina’s niet benaderbaar zijn zonder in te loggen. Ik heb daarom dit gedeelte in de web.config uit gecommentarieerd.

   1:  <system.web>
   2:      <!--
   3:      <authorization>
   4:        <deny users="?" />
   5:      </authorization>
   6:      -->

Op de ACS portal heb ik de return URL laten verwijzen naar de pagina die bij mij geheim is.

acs3

Dat is deze pagina in de app.

acs2

ACS implementeren is eigenlijk heel makkelijk, maar toch weer heel lastig. Er zijn veel knoppen waar je aan moet draaien om het goed te laten werken.

Ander dingetje wat je je moet realiseren. Het Access Control mechanisme zoals Windows Azure die aanbiedt bestaat voor het grootste gedeelte uit alleen de authenticatie. Weet je het nog Authenticatie, ben jij degene die je zegt dat je bent; Autorisatie, wat mag jij of welke rollen heb jij op deze website / webapplicatie. Wat je met ACS uit handen geeft is de authenticatie. Door middel van de login/password bij een van de Identity providers.

acs1

De autorisatie moet je zelf uitwerken in je eigen website of webapplicatie. De claims die je van de identity providers terugkrijgt zijn tokens (alleen FaceBook), e-mail adressen (niet bij Windows Live), Name (niet bij Windows Live) en een nameidentifier. De nameidentifier kun je wel gebruiken als key voor je rollen toekenningen systeem. En zoals je voorgaande leest, wil je bij Windows Live zelf vragen om e-mail adres en name (of je gaat met de nameidentifier zelf te raden bij Windows Live wat natuurlijk ook kan).

Veel plezier met WIF, ACS en Windows Azure. Wil je mijn web.config bekijken, mail mij (marcelmeijer @ planet.nl) dan. Mijn demo site is https://cloudtest.marcelmeijer.net .

Published by

Marcel Meijer

Op dit moment houdt hij zich voornamelijk bezig met Microsoft Azure, Cloud, C#, Software Ontwikkeling, Architectuur, etc. Hij werkt als consultant voor zijn eigen bedrijf JOEP-IT bv. In zijn vrije tijd is hij voorzitter, bestuurslid, eindredacteur en eventorganisator bij de SDN (Software Development Network). Sinds 1 oktober 2010 is hij MVP.

Leave a Reply

Your email address will not be published. Required fields are marked *