vrijdag 17 mei 2013

Autorisatie met ACS (Deel 2)

In de post "Windows Identity Foundation met ACS" heb je kunnen zien hoe je op jouw website/applicatie gebruik kunt maken van Identity Providers (IP's) zoals Facebook, LiveID en Yahoo!. Access Control System (ACS) speelde hierbij de rol van mediator (de federation provider), die de informatie van de verschillende IP's transformeert naar claims (jouw uiteindelijke paspoort). We hebben ook gezien dat voor autorisatiedoeleinden deze basisset niet echt bruikbaar is. 
In "Autorisatie met ACS (Deel 1)" heb ik beschreven hoe je de claims in ACS kunt verrijken met extra claims op basis van de binnenkomende claims van de IP. Daarnaast heb ik beschreven hoe je die claims op jouw website kunt gebruiken om rechten tot bepaalde delen van de website af te regelen. Het probleem bij deze benadering is, dat het wel erg bewerkelijk is om op die manier claims toe te kennen aan specifieke gebruikers.
In dit laatste deel laat ik zien hoe je de claims van ACS kunt verrijken met informatie uit jouw eigen database.

Wanneer een onaangemelde gebruiker op jouw site komt, wordt hij meteen doorverwezen naar een Identity Provide (IP). Wanneer de authenticatie slaagt, komt hij weer terug op jouw website (passieve STS) alwaar nogmaals bekeken wordt of de gebruiker geauthenticeerd is. Indien dat het geval is, mag hij door. Dit proces is een eenmalige actie, zodat hij niet telkens voor iedere pagina opnieuw zijn credentials hoeft op te geven. Dit principe staat bekend als Single Sign-On (SSO). Afbeelding 1 geeft weer hoe de aanmeldprocedure verloopt.

Afbeelding 1. Aanmeldprocedure (bron: Windows Azure)

  1. Gebruiker bezoekt website (RP = Relaying Party, om het moeilijker te maken)
  2. Gebruiker krijgt een lijstje van ondersteunde Identity Providers (Yahoo!, Google)
  3. Gebruiker wordt doorverwezen naar de IP van zijn keuze en meldt zich aan
  4. Gebruiker krijgt zijn security token (paspoort) als de aanmelding slaagt
  5. Gebruiker keert terug bij ACS alwaar het token wordt getransformeerd
  6. Gebruiker krijgt nu een ACS-token terug waarmee hij naar de website kan
  7. Gebruiker komt geauthenticeerd terug bij de website
Bij deze laatste check zou je nu de extra claims uit de database kunnen toevoegen. Hier hebben we meteen een probleem. Om rechten aan een gebruiker te kunnen toekennen, moet je eerst zijn identifier achterhalen, en die verschilt van provider tot provider. Aan die identifier valt niets af te lezen dus moet je ook een correlatie leggen met de gebruikersnaam. Bij sommige providers wordt de naam wel meegegeven die je dan kunt gebruiken, maar bij Live ID krijg je alleen die identifier terug. Je zou iets kunnen doen met een speciale webpagina die de identifier aan de aangemelde gebruiker presenteert die hij vervolgens naar de beheerder mailt.

Het datamodel kun je weer zo makkelijk of moeilijk maken als je wilt, maar uiteindelijk zul je de binnenkomende claims moeten verrijken. Dit kun je doen door gebruik te maken van de ClaimsAuthenticationManager (voeg hiervoor eerst een referentie naar System.IdentityModel en System.IdentityModel.Services toe). ClaimsAuthenticationManager nestelt zich, net zoals ClaimsAuthorizationManager, in de request pipeline van Internet Information Service (IIS). Het enige dat je hoeft te doen, is een nieuwe class te laten erfen van ClaimsAuthenticationManager en de methode Authenticate() overschrijven. Deze methode wordt alleen bij de eerste aanmelding aangeroepen en is dus de ideale plek om de claimset te verrijken. Via het "incomingPrincipal" argument kun je de identifier van de gebruiker achterhalen en de gerelateerde data uit de database vissen om vervolgens de extra claims eraan te hangen. In de code hieronder kun je zien hoe dat in zijn werk gaat.

public class MyAuthenticationManager : ClaimsAuthenticationManager
{
    public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
    {
        if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated)
        {
            ClaimsIdentity ci = incomingPrincipal.Identity as ClaimsIdentity;
            if (ci != null)
            {
                // Add roles from database here.
                ci.AddClaim(new Claim(ClaimTypes.Role, "User"));
                ci.AddClaim(new Claim(ClaimTypes.Role, "Admin"));
            }
        }
        return incomingPrincipal;
    }
}

Vervolgens moet je de module in de IIS pipeline injecteren en dat gaat, net zoals bij de AuthorizationManager, via de web.config.

<system.identityModel>
  <identityConfiguration>
    <claimsAuthenticationManager type="MvcApplication1.Auth.MyAuthenticationManager, MvcApplication1"/>
    <claimsAuthorizationManager type="MvcApplication1.Auth.MyAuthorizationManager, MvcApplication1"/>
  </identityConfiguration>
</system.identityModel>

En dat is eigenlijk alles. 

Claims Based Identity is een erg krachtige techniek om zowel de authenticatie als autorisatie mee af te handelen, maar op zich vrij lastig. Echter, met de Identity and Access Tool wordt het al een stuk eenvoudiger en tesamen met Access Control System (ACS) een peuleschil.  

Geen opmerkingen:

Een reactie posten