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: , , , , , , ,

OpenRasta for Rest-baserte tjenester

by Israr Khan 14. juli 2011 11:45

Rastafari man!

Har tidigere sett en del på å lage REST-baserte tjenester med WCF, blant annet med webHttpBinding og også med Rest Template-en1.

I mellomtiden har det skjedd en del, blant annet har WCF Web API2 blitt gitt ut i Preview 4, samt at jeg har sett litt mer på OpenRasta3.

WCF Web API virker som et veldig spennende initativ fra Microsoft for å gjøre utvikling av REST-baserte tjenester enklere, men er per nå kun i preview 4.
OpenRasta på sin side har vært i utviklingen side 2008, og for meg så virker det som et mer modent og stabilt rammeverk.

Tags: , , , , , , ,

Asp.Net | Koding

Rest-baserte tjenester med Azure Access Control Services

by Israr Khan 19. april 2011 16:03

Ok - etter litt jobbytte, nye impulser fra MIX og ansvar for en ny løsning går jeg i gang med enda et nytt prosjekt!
De neste innleggene mine kommer nok til å handle mye om følgende tema:

Rest, Json, API, ACS, Azure, Odata og t.o.m Sharepoint!

Men bare det å starte med testinga, lese seg opp på gode tutorial o.s.v kan ta tid, så rett før jeg var på vei til å gi meg fant jeg en som kan være verdt å dele:

http://msdn.microsoft.com/en-us/magazine/gg490345.aspx 

Tags: , , , , ,

Asp.Net | Koding

RestSharp

by Israr Khan 16. februar 2011 23:50

Har tidligere skrevet litt om konsumering av REST-baserte tjenester i C#, men biblioteket RestSharp har virkelig forneklet ting!

RestSharp is a simple, open source REST client for .NET designed primarily for consuming third-party HTTP APIs. 

Har blant annet brukt dette biblioteket i Trafikken - og anbefaler alle som skal utføre kall mot REST-tjenester å se på biblioteket. 


http://restsharp.org/ 

Tags: , , , , ,

Koding | Windows Phone 7

Konsumere REST-baserte tjenester i .Net

by Israr Khan 30. desember 2010 11:24

Av og til skal det være ganske vanskelige å finne noe fornuftig på nettet - selv med Google ;)

Skal du konsumere rest-baserte tjenester i .Net - kan du enten utføre HTTP-Request direkte mot tjenestene med accept json(e.l.) - eller gjøre det det på følgende måte(noe som jeg synes blir mye bedre):

WebChannelFactory<IBookmarkService> cf = new WebChannelFactory<IBookmarkService>(
    new Uri("http://localhost:55555/BookmarkService.svc"));
IBookmarkService channel = cf.CreateChannel();
Bookmarks bms = channel.GetPublicBookmarks("WCF");
foreach (Bookmark bm in bms)
    Console.WriteLine("{0}\r\n{1}", bm.Title, bm.Url);

For å kunne konsumere REST-tjenester på denne måten blir du nødt til å opprette et interface selv på klientsiden, noe som i mange tilfeller kan være verdt innsatsen.

Hele oppskriften finner du på "A Guide to Designing and Building RESTful Web Services with WCF 3.5" under "Consuming RESTful Services with WCF"

http://msdn.microsoft.com/en-us/library/dd203052.aspx , A Guide to Designing and Building RESTful Web Services with WCF 3.5.

Les mer på:
http://blogs.msdn.com/b/pedram/archive/2008/04/21/how-to-consume-rest-services-with-wcf.aspx 
http://blogs.msdn.com/b/kaevans/archive/2008/07/26/creating-a-rest-twitter-client-with-wcf.aspx


 

Tags: , , , , , ,

Koding

WCF Rest Template 40 - Behavior og IncludeExceptionDetailInFaults

by Israr Khan 22. desember 2010 10:28

Feilsøking av WCF-tjenester kan være både en fryd - og pest og plage! Jeg skal ikke gå inn på hvordan du går frem for å få med exceptions details med "vanlig" WCF (hint: Se lenker) - men når du ikke har de nødvendige elementene (I dette tilfellet "Services" i config-filen) - kan en lure på hvordan dette gjøres.

Hvis tjenesten din kaster en exception eller tryner i WCF rammeverket - vil du kun få ut :

Request Error
The server encountered an error processing the request. Please see the service help page for constructing valid requests to the service.

For WCF Rest Template vil en typisk config-fil se slik ut:

 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>
  <system.serviceModel>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <standardEndpoints>
      <webHttpEndpoint>
        <!--
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      
</webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

That's it! Så hvor pokker skal du legge inn service behavior for å inkludere exceptions? (En service behavior er tilknyttet en tjeneste - og som du ser her finnes det ingen services)
Det første vi må få lagt inn er faultExceptionEnabled="falseTrue" inn i standardEndpoint for å påse at vi får FaultExceptions ut til klienten.Mer...

Tags: , , , , ,

Koding

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