28. dubna 2017

Autentizace mobilní Xamarin aplikace vůči Azure


V tomto článku popíši, jak lze snadno řešit problematiku autentizace mobilní aplikace vůči backendu běžícího na infrastruktuře MS Azure. Tento konkrétní příklad popisuje autentizaci prostřednictvím Microsoft účtu. Obdobné je to ale i pro Facebook, Google ….

Nastavení zabezpečení na straně serveru

Pokud používáte klasickou WebApp v Azure tak je zapnutí zabezpečení velice snadnou záležitostí. V hlavním menu aplikace zvolte Authentication/Authorization. Přepínačem zapněte App Service Authentication. Azure vám nabídne všechny autentizační služby, které můžete použít.
 

V našem příkladu nás zajímá Microsoft autentizace. Klikněte tedy na Microsoft, zde je nutné zadat Client Id a Client Secret vaší aplikace. Pokud tyto údaje nemáte tak je nutné vaši aplikaci jednoduchým formulářem zaregistrovat. Odkaz je součástí konfigurační stránky.
To je vše, tímto krokem máme autentizaci na backendu funkční. Pozor! Autentizaci, ne autorizaci, autorizaci je potřeba řešit zvlášť, nejčastěji přímo v rámci vaší aplikace. Tím se ale nebudu v tomto článku zabývat.


Autentizace na straně mobilu

Nyní jsme ve stavu, kdy máme backend zabezpečený a my potřebujeme provést přihlášení uživatele na mobilním telefonu. Kdybychom nyní začali volat API v naší Web App tak jsou již zabezpečená a budeme dostávat chybový HTTP status 401 Unauthorized.
Naše mobilní aplikace je naprogramovaná v technologii Xamarin. Potřebujeme nejprve nainstalovat knihovnu která autentizaci vůči Azure řeší, ta se jmenuje Microsoft Authentication Library. Naleznete ji na nuget.org: https://www.nuget.org/packages/Microsoft.Identity.Client
Po nainstalování knihovny se můžeme pustit do programování.
// appUrl - adresa vasi WebApp
var client = new MobileServiceClient(appUrl);
// this - context který potřebujete předat, v našem případě je to Android Activity
var user = await Client.LoginAsync(thisMobileServiceAuthenticationProvider.MicrosoftAccount);
// získání user ID a auth tokenu po přihlášení uživatele
var userId = user.UserId;
var authTokenSettings = user.MobileServiceAuthenticationToken;

This Is It. V naší ukázce provádím autentizaci v Android aplikaci, vytvořím si objekt clienta, v konstruktoru mu předám pouze URL naší WebApp. Poté zavolám asynchronní metodu LoginAsync. Té předám kontext mé Activity class a řeknu jí, že chci použít Microsoft autentizaci. Tato metoda vyvolá přihlašovací dialog:
Knihovna neudělá nic jiného, než že nám zobrazí WebView s formulářem pro přihlášení. Po úspěšném přihlášení pokračuje náš kód dále a získáme pro nás velice důležitý AuthToken. Pokud by se uživatel nedokázal přihlásit a akci zrušil tak se vždy nastartuje znovu Activity kterou jsme metodě předali.
Výhodou je, že si context aplikace v cache do budoucna drží údaje. Uživatel se tedy příště nebude muset znovu přihlašovat, knihovna zajistí, že se autentizace provede bez nutnosti zadávat přihlašovací údaje.
Uživatel je tedy přihlášen a my potřebujeme využít získaný AuthToken k volání naší WebApp aby nám důvěřovala. Je potřeba tento token posílat v headeru každého requestu který jde na server. Klíč pro tento header má název X-ZUMO-AUTH.


Nastavení HttpClient může vypadat tedy například takto:
public static void SetClient(HttpClient client, string baseUrl, string authToken)
{
   client.BaseAddress = new Uri(baseUrl);
   client.DefaultRequestHeaders.Accept.Clear();
   client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
   client.DefaultRequestHeaders.Add("X-ZUMO-AUTH", authToken);
}

V Headeru posíláme Auth token a server by nám v tento okamžik měl začít na requesty odpovídat.

Problematika odhlášení

Knihovna pro autentizaci, kterou jsme použili má metodu LogoutAsync která by měla provést odhlášení. Bohužel mi tato metoda pro Android klienta absolutně nefungovala. Pokud budete mít tedy stejný problém, že Logout nefunguje a aplikace si v cache drží stále context posledního přihlášeného uživatele tak vám přináším workaround jak uživatele vždy s jistotou odhlásit.
Zavolejte na clientovi metodu LogoutAsync a hned po zavolání této metody proveďte vymazání aplikační cache pro cookies. Například tímto kódem:
async Task ClearApplicationCache()
{
   if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
        Android.Webkit.CookieManager.Instance.RemoveAllCookies(null);
   else
        Android.Webkit.CookieManager.Instance.RemoveAllCookie();
}
Tím se provede odmazání všech cookies pro context naší aplikace a uživatel je opravdu odhlášen – bude muset znovu zadat své přihlašovací údaje.

Autor článku: Kamil Praum, CCA Group a.s.

Žádné komentáře:

Okomentovat