Rest-tjenester med WCF Web API, ACS og SWT - uten WIF - Del 1: intro, oppsett av ACS og klient

by Israr Khan 16. august 2011 19:57
Da jeg fortalte en kompis at det var ganske knotete å arbeide med "det å lage REST-baserte tjenester med WCF WebAPI Preview 4 og sikre disse ved hjelp av ACS og SWT, alternativt SAML uten å bruke WIF" - var svaret hans: "Ja, tror jeg ser hva som er saken her; det er for mange forkortelser" ;) Så for at du skal slippe å måtte gå igjennom samme research som meg - gir jeg ut en serie med poster som vil vise deg nettopp hvordan du kan gjøre dette :)

Så for å ta en kort oppsummering med lenker og info du bør se på før vi begynner (med god hjelp fra Wikipedia og andre nettsider)

REST-tjenester: 

A RESTful web service (also called a RESTful web API) is a simple web service implemented using HTTP and the principles of REST. It is a collection of resources, with three defined aspects:
- the base URI for the web service, such as http://example.com/resources/
- the Internet media type of the data supported by the web service. This is often JSON, XML or YAML but can be any other valid Internet media type.
- the set of operations supported by the web service using HTTP methods (e.g., POST, GET, PUT or DELETE). 

Windows Identity Foundation WIF:
http://www.microsoftpdc.com/2009/P09-21
 
Sånn - da får alle newbiesene noe å lese på - men hvis du kom hit for å få svar på hvordan du faktisk bruker ACS med WCF Web API uten WIF med SWT, så starter vi nå!
Scenarioet i dette tilfellet er som følger:
 


1: Sluttbruker autentiserer seg mot din web-applikasjon, klient e.l. Hvordan din sluttbruker autentiserer seg er ikke relevant i dette tilfellet.
2: Din klient(altså - ikke sluttbruker, men din web-applikasjon e.l) kommuniserer mot en WCF tjeneste som er basert på WCF Web Api og REST.
3: Klienten ber om å få token fra ACS - hvor den bruker enten et passord, en nøkkel eller et sertifikat for å autentisere seg mot ACS.
4: Klienten sender dette tokenet til WCF Rest-tjeneste som deretter validerer dette.
5: Basert på om det tokenet er valid eller ikke, vil din web-applikasjon få tilgang/ikke tilgang.


Før du kan begynne trenger du en Azure-konto samt WCF Web API. 
Deretter vil stegene være noe ala følgende: 
1: Sette opp ACS med korrekt innstillinger.
2: Opprette en klient som tar i bruk ACS og henter ut en gyldig token og bruker denne i kallet til REST-tjenesten. 
3: Opprette en REST-tjeneste som godtar SWT-er fra ACS-en
Grunnen til at jeg vil opprette klienten først - er rett og slett at jeg synes det er enklere å forstå hvordan alt henger sammen ved å opprette klienten først kontra en tjeneste som validerer noe du ikke vet hvordan du får tak i :)
 
Oppsett av ACS

Strengt talt vil du finne bøttevis av tutorials som går igjennom hvordan du gjør dette - men hvor ofte kommer du ikke til tutorials på nettet som er halv-ferdige hvor det som er en selvfølge for forfatteren ikke nødvendigvis er det for deg? 
Så da tar jeg en rask gjennomgang av hvordan du sette opp ACS - uten nødvendigvis å fortelle deg i detaljer hvorfor.
 
Opprett namespace i ACS: 
Logg inn på Azure -> velg Service Bus, Access Control & Caching -> New.
Skriv inn et valgfritt namespace - noe som bør reflektere din organisasjon, applikasjon e.l.
 

2: Vent til namespacet går over fra å være i status "Activating" til "Active".

3: Klikk på knappen "Access Control Service" på topp-menyen for å gå inn på kontrollpanelet til selve namespacet.
 

Gratulerer! Da har du fått opp ditt første ACS namespace! :)
 
Service identity
http://msdn.microsoft.com/en-us/library/gg185945.aspx

Det neste vi er nødt til å gjøre er å opprette en identitet for din klient, altså webapplikasjon som skal hente ut tokens fra ACS.
Klikk deg inn på "Service Identities" og velg "Add".

Service identity settings:
Name:
Dette blir brukernavnet til din klientapplikasjon, i mitt tilfellet "KodeverkClient"
Description: Ja.. Du har ikke kommet så langt i denne tutorialen uten å vite at description er description, og at den i tillegg er optional ;)
Credential setting
Type: Password
Passord: Her har jeg valgt å bruke "kodeverkPass" (et passord jeg aldri har brukt i noe reellt sted - i tilfelle du lot deg friste til å prøve det ut på siden her)

Resten kan du la være, og trykk "Save".
 
Da har vi satt opp vår kommende klient som en gyldig Service Identity i ACS. Neste steg er å sette opp vår Relying Party Application
 
Relying Party Application
http://msdn.microsoft.com/en-us/library/gg185906.aspx

Kort fortalt vil en relying party application være en webtjeneste, webapplikasjon eller en applikasjon som skal godta at ACS autentiserer brukere på vegne av seg.
Klikk på "Relying party applications" og "Add".
Name: KodeverkService" - Kan være hva du vil.
Mode: Manually
Realm: http://www.kodeverk.net/RestAPI. Et realm, eller scope, eller domenet er det området hvor applikasjonen befinner seg. For tjenester kan dette være en fiktiv adresse, for webapplikasjoner må applikasjonen faktisk befinne seg på, eller under området som er spesifisert som realm.
Resten kan være som det er - frem til du kommer til Token Format.

Token Format: SWT
Identity providers: En av styrkene til ACS er å tillate dine applikasjoner å kun måtte forholde seg til en type token, f.eks. SAML eller SWT, men likevel å tillate dine _brukere_ å benytte seg av flere forskjellige innloggingsmekanimer, inkludert Facebook, Windows Live, Google, Active Directory o.s.v.(Identity provider = IDP). For vårt tilfelle ønsker vi ikke å tillate noen andre enn vår godkjent klient som vi satte opp som service identity å kunne benytte seg av ACS for å autentisere opp mot vår relying party application - derfor huker vi bort Windows Live som Identity Provider.
Generer en ny signeringsnøkkel - og trykk Save.  
 
Rule groups spiller en større rolle når vi skal transformere informasjon vi får fra forskjellige IDP-er, som f.eks Facebook, Live, Google o.s.v. til et felles format. I vårt tilfelle ønsker vi kun å sikre vår innlogging basert på at det er en gyldig service identity.


Vi går derfor inn på "Rule Groups" fra menyen på høyre side, og velger "Default Rule Group For KodeverkService" (eller noe annet hvis din Relying party application heter noe annet). Velg deretter "Add", og sett opp ACS som issuer - i stedetfor et IDP.

Resten kan du la være som det er - og trykk "Save".
 
Sånn! Da har vi satt opp det nødvendige for å kunne bentte oss av ACS i vårt scenario.
Av viktig informasjon som vi vil trenge fremover er følgende:

Namespace: kodeverk
Service identity:
Brukernavn til service identity (KodverkClient)
Passord til service identity (kodeverkPass)

Relying party application
Realm/Scope: (http://www.kodeverk.net/RestAPI)
SigningKey: (Zl1vqy0h45UImmzPzK7EuSUXo6yGpw1nAYazZGdal6A=)
 
Klienten

For å simulere vår web-applikasjon oppretter vi en konsoll-applikasjon som kommer til å utføre følgende:
1: Benytte seg av service identity brukernavn, passord og realm for å få ut token fra ACS
2: Benytte token fra ACS for å kalle underliggende REST-tjeneste.
Koden til en slik klient kan f.eks. se slik ut:

http://msdn.microsoft.com/en-us/library/ee706727.aspx
static void Main(string[] args)
        {
            var token = GetTokenFromACS();
        }

        private static string GetTokenFromACS()
        {
            // request a token from ACS
            WebClient client = new WebClient();
            client.BaseAddress = "https://kodeverk.accesscontrol.windows.net";

            NameValueCollection values = new NameValueCollection();
            values.Add("wrap_name", "KodeverkClient");
            values.Add("wrap_password", "kodeverkPass");
            values.Add("wrap_scope", "http://www.kodeverk.net/RestAPI");

            byte[] responseBytes = client.UploadValues("WRAPv0.9/", "POST", values);

            string response = Encoding.UTF8.GetString(responseBytes);

            Console.WriteLine("\nreceived token from ACS: {0}\n", response);

            return HttpUtility.UrlDecode(
                response
                .Split('&')
                .Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))
                .Split('=')[1]);
        }


OBS
: Hvis du velger å opprette en konsoll-applikasjon, er du nødt til å endre Target framework fra  .Net Framework 4 Client Profile til .Net Framework 4 - og deretter legge til en referanse til System.Web (grunnet HttpUtility).


Nå er det natta for meg! I neste tutorial kommer de virkelige godsakene hvor vi legger inn en egen MessageChannel i WCF Web API for å validere den innkommende SWT-en i REST-tjenesten samt utvider klienten vår til å kalle på vår nye tjeneste. :)
 

Tags: , , , , , , ,

Om meg

Kodeverk.net er drevet av .Net-utvikler Israr Khan.

Han jobber som gruppeleder og  seniorkonsulent for Capgemini Norge.

Hans fokusområder er alt innenfor .Net-verden, og har foreløpig tilgode å finne noe som han ikke finner av interesse innenfor teknologien. Han er drevet av genuin interesse for teknologi og lever for faget.


 

View Israr Khan's profile on LinkedIn

Month List