Jste vývojáři .NET a vždy jste chtěli vytvořit mobilní aplikaci? Nebo jste možná zkoušeli vytvářet nativní mobilní aplikace pro Android nebo iOS, ale tyto jazyky se vám nelíbily? Pak máte štěstí! Svět .NET byl obdařen Xamarinem; sadou nástrojů, která vám umožní vytvářet mobilní aplikace pro Android, iOS a Windows v rámci Visual Studia.

Xamarin má dvě hlavní varianty: Xamarin: platforma Xamarin (Xamarin.iOS a Xamarin.Android) a Xamarin.Forms. S Xamarin.Forms lze naprostou většinu obchodní logiky a uživatelského rozhraní napsat v rámci jednoho sdíleného projektu, který vytváří plně funkční aplikace pro všechny 3 operační systémy iOS, Android a Windows (UWP). Naproti tomu platforma Xamarin je do značné míry specifická práce pro danou platformu a podobá se spíše psaní nativních aplikací, ale v jazyce C#.

V tomto tutoriálu se budu blíže zabývat platformou Xamarin a sadou nástrojů pro operační systém Android známou jako Xamarin.Android. Celkovým cílem je umožnit vám vytvořit jednoduchou nativní aplikaci pro Android včetně základní autentizace uživatele.

Nastavení Visual Studia a vašeho prostředí

Pro další postup budete potřebovat kopii Visual Studia a pracovní příručku ‚Mobile development with .NET‘. Tuto funkci můžete povolit buď při první instalaci aplikace Visual Studio, nebo k ní získáte přístup z položky nabídky ‚Nástroje -> Získat nástroje a funkce…‘:

Při testování a spouštění aplikace máte na výběr, zda tak budete činit pomocí emulátoru Androidu spuštěného na vašem vývojovém počítači, nebo přímým připojením k existujícímu zařízení Android. Neexistuje zde žádná správná volba a různí vývojáři dávají přednost různým formám. Pokud zvolíte první možnost, musíte se po výběru pracovní zátěže ujistit, že na pravém panelu („Podrobnosti o instalaci“) jsou zaškrtnuta políčka Intel Hardware Accelerated Execution Manager a Google Android Emulator (jak je vidět výše).

Ověření prostředí Android ve Visual Studiu

Chcete-li ověřit, že se vše správně nainstalovalo a bylo správně nakonfigurováno, přejděte na „Nástroje -> Možnosti -> Xamarin -> Nastavení Androidu“ a zkontrolujte, zda jsou cesty k Java Development Kit Location a Android SDK Location platné (tj.tj. mají zelené zaškrtnutí):

Pokud některá z nich chybí, budete muset Java Development Kit, respektive Android SDK nainstalovat ručně.

Vytvoření aplikace Xamarin

Začněte vytvořením nového projektu a vyberte hlavní šablonu ‚Android App (Xamarin)‘ (najdete ji v nabídce Android). Na další stránce budete chtít vybrat možnost ‚Single View App‘, protože je to skvělá startovací šablona pro práci.

Co se týče minimální verze systému Android, je to něco, co závisí na vaší osobní volbě jako vývojáře. Existuje zde kompromis mezi možností přístupu k nejnovějším a nejlepším funkcím API v novějších verzích a podporou vašich zákazníků, kteří mají starší verze. Aby vám společnost Google pomohla při rozhodování, zveřejňuje v poměrně pravidelných intervalech údaje o distribuci verzí platformy, které shromažďuje v rámci svého distribučního panelu. Osobně se přikláním k verzi 5.0 nebo 6.0 v závislosti na tom, zda se jedná o aplikaci pro veřejnou spotřebu, nebo o aplikaci na zakázku určenou pouze pro firemní telefony (tj. ty budou mít pravděpodobně nejnovější aktualizace); v tomto příkladu jsem zvolil druhou možnost. Všimněte si, že tato verze se liší od cílové verze Androidu a ta by měla být vždy nastavena na nejnovější vydanou verzi SDK, protože nic menšího nebude do obchodu Google Play přijato.

Po vytvoření této verze zbývá už jen importovat požadované balíčky NuGet. Pro tento návod budete potřebovat:

  • Xamarin.OpenId.AppAuth.Android – Pro ověření uživatele budete používat standard OpenID Connect (vylepšení OAuth 2.0). Nejjednodušší způsob, jak implementovat klientský kód, který dodržuje tuto specifikaci, je použití klienta AppAuth SDK pro Android, a užitečné je, že Xamarin portoval balíček této funkce, který je k dispozici k použití.
  • System.IdentityModel.Tokens.Jwt – Metoda ověřování zde používá webové tokeny JSON. Pro získání potřebných dat z těchto tokenů budete potřebovat tento balíček.

Dále budete potřebovat také tyto dva balíčky, protože na ně AppAuth spoléhá:

  • Xamarin.Android.Support.v4
  • Xamarin.Android.Support.CustomTabs

Seznámení s projektem Xamarin

Pokud jste nikdy předtím nepracovali se systémem Android, jedním z klíčových principů, které je třeba pochopit, je koncept aktivity. Aktivity jsou komponenty, které slouží k zobrazení uživatelského rozhraní; v nejzákladnější podobě si Aktivity můžete představit jako obdobu stránek v aplikaci, mezi kterými může uživatel procházet. Aktivita je v kódu reprezentována třídou, nicméně podobně jako ke stránce v ASP.NET k ní můžete (a téměř vždy budete) přiřadit soubor rozvržení založený na XML (soubor .axml) pro zobrazitelný design. Všechny nové projekty vytvářejí soubor ‚MainActivity.cs‘ a ‚activity_main.axml‘, který se spustí jako první Aktivita (tj. stránka) po otevření aplikace. To lze změnit na jakoukoli jinou Aktivitu využitím vlastnosti MainLauncher = true v rámci atributu Activity třídy.

Zdroje jsou navrženy tak, aby se s nimi pracovalo v jejich vlastním adresáři, a dodržují poněkud přísnou konvenci pojmenování. Důrazně doporučuji ukládat co nejvíce zdrojů do tohoto adresáře, protože to zjednodušuje opakované použití těchto proměnných pro váš další vývoj. V adresáři ‚values‘ adresáře Resources se nacházejí soubory se specifickým určením:

  • Strings.xml – Hostí všechny řetězce určené pro uživatele. Tento je obzvláště důležité používat, protože umožňuje lokalizovat řetězce pro globální publikum.
  • Styles.xml – Zde najdete atributy pro stylování objektů návrhu; představte si jej jako soubor CSS.
  • Colors.xml – Místo pro uložení odkazů na barvy, které nejčastěji používáte jako součást stylování.
  • Dimens.xml – Jak může název napovídat, místo, kde definujete nastavené rozměry pro rozvržení vaší aplikace.

Další významné adresáře se neřídí žádnou konvencí pro pojmenování svých souborů, ale musí obsahovat určité typy souborů:

  • Rozvržení – Místo pro uložení vašich souborů .axml. Tyto soubory definují úplné rozvržení Aktivity, komponenty rozvržení, které programově generujete a vyplňujete, rozvržení dialogových (výstražných) oken atd.
  • Menu – Kde najdete definice menu a jejich položek. Jedná se o soubory .xml, které mají jako kořenový prvek menu a podřízené prvky item, z nichž lze seskupovat prvky group. Nejběžnější nabídky, se kterými se setkáte, jsou přetékající nabídka (z tlačítka se třemi svislými tečkami) nebo navigační nabídka (z domovského tlačítka „hamburger“).
  • Mipmap – Kde chcete definovat obrázky, které je třeba škálovat v závislosti na hustotě obrazovky, tj. ty, na které odkazují jiné aplikace a které nejsou používány interně. Ikona aplikace je nejběžnějším obsahem, který byste umístili do adresářů mipmap.
  • Drawable – Není standardní součástí výchozí šablony projektu, ale můžete si ji vytvořit sami. Sem ukládáte své obrázky/kreslitelný obsah, který chcete použít v aplikaci, např. úvodní obrazovku, vlastní návrhy ukazatele průběhu, ikony použité v aplikaci atd.

Nakonec, pokud máte nějaké soubory surového obsahu, které chcete použít jako součást aplikace (např. textový soubor nebo soubor s písmem), pak je umístěte do adresáře Assets. Jako Assets budou tyto soubory nasazeny spolu s vaší aplikací, abyste k nim mohli přistupovat pomocí Asset Manageru.

Chcete-li se dozvědět více o Assets a Resources a o tom, jak je používat, v každém adresáři nově vytvořeného projektu najdete praktické textové soubory „About“.

Přidejte do Xamarinu ověřování uživatelů pomocí OpenID Connect

Většina aplikací v dnešní době vyžaduje nějakou formu identifikace uživatele, aby vývojáři mohli nabízet zážitky na míru a aby uživatelé zase mohli uchovávat svá data na různých zařízeních/instalacích. Kromě toho je zde otázka řízení přístupu, která může být užitečná pro autorizaci podmnožiny uživatelů pro další funkce. To samozřejmě může být poměrně pracný úkol, zejména pokud se zabýváte tvorbou aplikací a pro každou z nich budete potřebovat nový systém. Naštěstí s nástrojem Okta můžete aplikaci nastavit během pouhých několika minut a veškerá náročná práce je pak hotová za vás! Služba Okta je kompatibilní se standardem OAuth 2.0 a je certifikovaným poskytovatelem OpenID Connect, a tak dokonale spolupracuje s klientem SDK AppAuth pro všechny vaše potřeby ověřování a autorizace.

Nastavení aplikace Okta

Nejprve byste měli ve svém účtu Okta nastavit novou aplikaci pro tento projekt. Pokud ještě žádnou nemáte, je vytvoření nového vývojářského účtu navždy zdarma opravdu snadné.

Jakmile to dokončíte a přihlásíte se do vývojářského panelu, poznamenejte si adresu Org URL, protože ji budeme potřebovat později:

Na panelu přejděte na kartu „Aplikace“ a odtud „Přidat aplikaci“. Vytváříte nativní aplikaci pro Android, takže je nejlepší zvolit šablonu platformy ‚Native‘.

Na této stránce přidejte název aplikace a vše ostatní ponechte jako výchozí. Po uložení si poznamenejte URI pro přesměrování přihlášení a ID klienta, protože je budete potřebovat dále.

Abyste mohli tyto tři hodnoty z Okta v budoucnu snadno používat, doporučuji je umístit do vlastní statické třídy v novém adresáři pro logiku ověřování:

public static class Configuration{ public const string ClientId = "{yourClientId}"; public const string LoginRedirectUri = "{yourRedirectUri}"; public const string OrgUrl = "https://{yourOktaDomain}";}

Vytvoření poskytovatele ověřování

Vynecháme z cesty kotlíkový kód. Musíte aplikaci nakonfigurovat tak, abyste ji informovali o svém schématu přesměrování URI. Toto schéma je vaše URI přesměrování přihlášení (ve standardním tvaru názvu reverzní domény) bez cesty. Například z výše uvedeného snímku obrazovky by mé schéma bylo ‚com.oktapreview.dev-123456‘.

Nejjednodušší způsob, jak to udělat, je vložit níže uvedený úryvek filtru záměrů do souboru AndroidManifest.xml ve složce Properties vašeho řešení. Do tagu Application přidejte následující XML a změňte hodnotu schématu na svou vlastní:

<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="{yourRedirectRriScheme}" /> </intent-filter></activity>

Také musíte definovat model pro výsledek vaší autorizace pomocí jednoduché třídy. V rámci kódu sice nebudu používat všechny hodnoty, které jsem napsal níže, ale ukážu, jak je vyplnit, abyste je mohli použít později. Protože se jedná o součást modelu vaší aplikace, vytvořte složku Models a přidejte do ní třídu AuthorizationResult.cs. Poté přidejte následující kód:

public class AuthorizationResult{ public string AccessToken { get; set; } public string IdentityToken { get; set; } public bool IsAuthorized { get; set; } public string RefreshToken { get; set; } public string Scope { get; set; }}

Android nemá globální stav, se kterým byste mohli pracovat, a tak pokud chcete předávat jednoduché hodnoty mezi aktivitami, nejlépe to uděláte pomocí funkce Extras na objektu Intent. Objekt Intent je v systému Android předdefinovaná třída a další základní koncept, který je třeba pochopit. Je to abstrakce operace, která má být provedena (tj. vašich „záměrů“), a chcete-li přejít dopředu k jiné aktivitě, musíte vytvořit instanci této třídy s tím, ke které aktivitě „hodláte“ přejít. Vlastnosti Extras na objektu Intent jsou v podstatě jen slovníkem klíčů k hodnotám objektu a přistupuje se k nim pomocí Put a typizovaných metod Get.

Přestože tyto metody udržují použití relativně přehledné a snadné, osobně bych rád udržoval veškerý přístup k nim v rámci jejich vlastní třídy (přesněji řečeno třídy Extensions), abych zachoval lepší oddělení zájmů. To je nesmírně užitečné, protože nemusíte přistupovat ke klíčům napříč třídami a můžete zajistit typovou bezpečnost při vkládání a získávání těchto hodnot. Ve svém zprostředkovateli autorizace budete chtít: uložit AuthState, umět zkontrolovat, zda tam je, a vrátit ho, pokud tam je. Vytvořte v kořenovém adresáři řešení novou složku s názvem Extensions. Poté přidejte novou třídu s názvem IntentExtensions.cs. Vytvořte třídu public a static, pak přidejte následující kód uvnitř třídy:

public const string AuthStateKey = "authState";public static string GetAuthStateExtra(this Intent intent){ return intent.GetStringExtra(AuthStateKey);}public static bool HasAuthStateExtra(this Intent intent){ return intent.HasExtra(AuthStateKey);}public static void PutAuthStateExtra(this Intent intent, AuthState authState){ intent.PutExtra(AuthStateKey, authState.JsonSerializeString());}public static bool TryGetAuthStateFromExtra(this Intent intent, out AuthState authState){ authState = null; if (!intent.HasAuthStateExtra()) { return false; } try { authState = AuthState.JsonDeserialize(intent.GetAuthStateExtra()); } catch (JSONException) { return false; } return authState != null;}

Nyní je čas definovat poskytovatele autorizace, AuthorizationProvider.cs ve složce Authentication, kterou jste vytvořili předtím pro třídu Configuration.cs. Nejprve odstraňte všechny příkazy using uvnitř nově vytvořené třídy a poté deklarujte konfiguraci jako proměnné static readonly:

private static readonly Uri ConfigurationEndpoint = Uri.Parse($"{Configuration.OrgUrl}/oauth2/default/.well-known/openid-configuration");private static readonly string Scopes = new { "openid", "profile", "email", "offline_access" };

Koncový bod konfigurace je standardem v OpenID jako koncový bod zjišťování, abyste zjistili vše, co je podporováno. Všimněte si, že zde jsem napsal, že se používá „výchozí“ název poskytovatele. Pokud máte jiného poskytovatele, budete to zde chtít změnit. Všimněte si také, že je zde použita příchuť Android.Net třídy Uri, a nikoli verze System – aby to fungovalo, budete muset přidat první z nich do svého použití nebo plně kvalifikovat typ. Proměnná Scopes, stejně jako každý jiný systém OpenID, definuje, k čemu jsme oprávněni přistupovat.

Dále byste měli deklarovat své členské proměnné:

private AuthorizationRequest authorizationRequest;private PendingIntent completedIntent;private AuthState authorizationState;private readonly AuthorizationService authorizationService;private readonly Context context;private readonly TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();

Krátké vysvětlení ke každé z nich:

  • Žádost o autorizaci a vyplněný záměr jsou parametry vytvořené pro použití při provádění autorizačního volání. Zde jsem je zapsal jako globální proměnné, abych minimalizoval množství předávání parametrů do různých metod.
  • Proměnná authorizationState, jak se jmenuje, definuje aktuální daný stav autorizace.
  • Proměnná authorizationService obsahuje instanci autorizační služby.
  • Proměnná context zde patří volající aktivitě, takže se na ni můžete v případě potřeby odvolat.
  • Nakonec proměnná taskCompletionSource umožňuje provést všechna tato volání asynchronně a po dokončení je vrátit.

Nyní byste měli v konstruktoru definovat hodnoty těchto readonly proměnných a deklarovat veřejné metody, které bude váš kód volat:

public AuthorizationProvider(Context context){ authorizationService = new AuthorizationService(context); this.context = context;}public async Task<AuthorizationResult> SignInAsync(){ ...}public void NotifyCallback(Intent intent){ ...}

Metoda SignInAsync je, jak jste asi uhodli, asynchronní metoda pro přihlášení uživatele. Vrací třídu AuthorizationResult, kterou jste napsali dříve. NotifyCallback Na druhou stranu slouží k tomu, aby volající aktivita po návratu z externí přihlašovací stránky zavolala zpět poskytovatele autorizace a dala mu vědět, že je hotovo. Metodu přihlášení jsem rozdělil do několika podprogramů a vypadá takto:

AuthorizationServiceConfiguration serviceConfiguration = await AuthorizationServiceConfiguration.FetchFromUrlAsync(ConfigurationEndpoint);BuildAuthorizationRequest(serviceConfiguration);BuildCompletedIntent(serviceConfiguration);return await RequestAuthorization();

V tomto jste definovali konfiguraci služby, sestavili požadavek na autorizaci a záměr volat po dokončení autorizace a pak čekat na požadavek autorizace. Sestavení požadavku na autorizaci je následující:

private void BuildAuthorizationRequest(AuthorizationServiceConfiguration serviceConfiguration){ AuthorizationRequest.Builder builder = new AuthorizationRequest.Builder( serviceConfiguration, Configuration.ClientId, ResponseTypeValues.Code, Uri.Parse(Configuration.LoginRedirectUri)); builder.SetScope(string.Join(" ", Scopes)); authorizationRequest = builder.Build();}

Úkolem této metody je abstrahovat od práce AuthorizationRequest.Builder a vytvořit požadavek. Dále je třeba sestavit Intent pro okamžik, kdy bude operace dokončena:

private void BuildCompletedIntent(AuthorizationServiceConfiguration serviceConfiguration){ Intent intent = new Intent(context, typeof(MainActivity)); intent.PutAuthStateExtra(new AuthState()); completedIntent = PendingIntent.GetActivity(context, authorizationRequest.GetHashCode(), intent, 0);}

„Záměr“, který zde chcete provést, je návrat do vašeho MainActivity s připojeným novým AuthState. Jako poslední se v tomto toku řeší provedení požadavku:

private async Task<AuthorizationResult> RequestAuthorization(){ authorizationService.PerformAuthorizationRequest(authorizationRequest, completedIntent); await taskCompletionSource.Task; return new AuthorizationResult() { AccessToken = authorizationState?.AccessToken, IdentityToken = authorizationState?.IdToken, IsAuthorized = authorizationState?.IsAuthorized ?? false, RefreshToken = authorizationState?.RefreshToken, Scope = authorizationState?.Scope };}

Jelikož PerformAuthorizationRequest je synchronní a vrací void, kód čeká na člen taskCompletionSource, protože ví, že bude vždy nastaven až po získání odpovědi. V tom samém okamžiku víte, že stav autorizace bude vyplněn (pokud se vše podařilo), a tak můžete vrátit jejich hodnoty jako součást AuthorizationResult.

Druhá veřejná metoda NotifyCallback, jak jsem se již zmínil, je to, co chcete, aby třída MainActivity zavolala zpět, jakmile se spustí vaše výše uvedená completedIntent. V této metodě chcete ověřit odpověď, vhodně aktualizovat stav a v případě úspěchu provést požadavek na výměnu tokenu:

if (!intent.TryGetAuthStateFromExtra(out authorizationState)){ taskCompletionSource.SetResult(false); return;}AuthorizationResponse authorizationResponse = AuthorizationResponse.FromIntent(intent);AuthorizationException authorizationException = AuthorizationException.FromIntent(intent);authorizationState.Update(authorizationResponse, authorizationException);if (authorizationException != null){ taskCompletionSource.SetResult(false); return;}authorizationService.PerformTokenRequest(authorizationResponse.CreateTokenExchangeRequest(), ReceivedTokenResponse);

Tady vidíte, že v případech neúspěchu jsem nastavil výsledek taskCompletionSource na false, a tím se odblokuje výše uvedená metoda RequestAuthorization. Metoda PerformTokenRequest také přebírá delegáta ReceivedTokenResponse, který se spustí po jejím dokončení. Tato metoda vypadá následovně:

private void ReceivedTokenResponse(TokenResponse tokenResponse, AuthorizationException authorizationException){ authorizationState.Update(tokenResponse, authorizationException); taskCompletionSource.SetResult(true);}

V tuto chvíli byste měli mít všechny potřebné autorizační údaje, a tak můžete vhodně aktualizovat stav (kde najdete hodnoty, které se mají vrátit z metody sign in) a nastavit výsledek pro odblokování úlohy taskCompletionSource.

Implementace ověřování do rozhraní Xamarinu

Pokud si to přejete, můžete v rámci úklidu odstranit všechny odkazy na „plovoucí akční panel“ (psaný také jako „FAB“) v souborech hlavní třídy aktivity/axml, protože jsou v této fázi zbytečným balastem.

Abyste uživateli umožnili přihlášení, musíte nyní tuto funkci implementovat do uživatelského rozhraní. Vzhledem k výchozímu návrhu by nejintuitivnějším způsobem, jak to provést, bylo přidat položku do přetékající nabídky v pravém horním rohu. To můžete provést úpravou souboru menu_main.xml ve složce „Resources -> menu“ a přidáním této položky jako potomka značky menu:

<item android:id="@+id/action_signin" android:orderInCategory="100" android:title="@string/action_signin" app:showAsAction="never" />

Pomocí tohoto kódu jste vytvořili novou možnost s názvem, který bude definován v souboru řetězcových zdrojů. Jak již bylo zmíněno dříve, v systému Android je nejlepší praxí umístit veškerý text směřující k uživateli do souboru string resources. Chcete-li deklarovat tento údaj, upravte soubor strings.xml ve složce ‚Resources -> values‘ a přidejte tyto řádky:

<string name="action_signin">Sign In</string><string name="welcome_message_format">Hi, %1$s!</string>

Nejenže jsem zde deklaroval řetězec pro tlačítko ‚Sign In‘, ale také jsem výše přidal řetězec pro uvítací zprávu pro uživatele po jeho přihlášení. Ekvivalentem kódu jazyka C# je this string would be „Ahoj, {0}!“`, kde je zástupný znak typu string.

Všimněte si, že při všech aktualizacích těchto souborů založených na zdrojích se automaticky přegeneruje třída Resource.designer.cs s novými ID pro každý vytvořený objekt, na který se můžete v kódu odkazovat. Pokud to u konkrétního souboru nefunguje, vyberte jej v Průzkumníku řešení a podívejte se do okna Vlastnosti. Ujistěte se, že vlastnost CustomTool je nastavena na hodnotu MSBuild:UpdateGeneratedFiles, protože pravděpodobně chybí a brání souboru návrháře, aby jej rozpoznal jako prostředek.

Dále přidejte ProgressBar do stávajícího souboru activity_main.axml rozvržení:

<ProgressBar android:id="@+id/signin_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:paddingBottom="12dp" android:visibility="gone" />

Tento ProgressBar (nebo spinner, jak je tomu v tomto případě), má ID, na které se můžete odkazovat pomocí kódu, a je nastaven tak, aby se nacházel kolem středu obrazovky. Viditelnost je prozatím nastavena na hodnotu pryč, ale jakmile bude váš autorizační kód spuštěn, můžete jej nastavit na viditelný a informovat uživatele, že je aplikace zaneprázdněna.

Teď máte tlačítko pro otevření ověřování a spinner průběhu, který uživatele informuje, že je aplikace zaneprázdněna, je čas je použít. V rámci své třídy MainActivity přidejte do atributu Activity (nad záhlaví třídy) následující vlastnost:

LaunchMode = LaunchMode.SingleTask

Tato vlastnost zajistí, že bude existovat pouze jedna instance třídy MainActivity a nebudete neustále otevírat nové. Jakmile to uděláte, přidejte statickou členskou proměnnou pro AuthorizationProvder, kterou jste napsali výše, a vytvořte její instanci v rámci existujícího přepisu metody OnCreate. Všimněte si, že by to mělo být provedeno za stávajícím kódem v rámci metody:

private static AuthorizationProvider authorizationProvider;protected override void OnCreate(Bundle savedInstanceState){ ... authorizationProvider = new AuthorizationProvider(this);}

Dále přepište metodu OnNewIntent. Účelem je, abyste při vytvoření nového záměru této třídy (tj. při návratu externího přihlašovacího okna) zavolali metodu NotifyCallback z AuthorizationProvider. Součástí je také rychlá kontrola, zda se jedná o očekávaný tok:

protected override void OnNewIntent(Intent intent){ base.OnNewIntent(intent); if (intent != null && intent.Data.Path.Equals("/callback", StringComparison.OrdinalIgnoreCase)) { authorizationProvider.NotifyCallback(intent); }}

Nyní přidejte kód za přidanou položku nabídky. Do stávajícího přepisu metody OnOptionsItemSelected přidejte příkaz if s voláním nové metody, která bude zpracovávat proces přihlášení takto:

if (id == Resource.Id.action_signin){ OnSignInAttempted(); return true;}

Tato nová metoda začne tím, že zviditelní ProgressBar, kterou jste před chvílí přidali; pro načtení libovolné komponenty ze souboru rozvržení použijte obecnou metodu FindViewById a jako její argument zadejte ID komponenty. Poté proveďte volání metody SignInAsync a vyčkejte na její výsledek. Po vrácení volání je pak výsledek ověřen jako autorizovaný. Pokud se tato autorizace z jakéhokoli důvodu nezdařila, zobrazí se chybový dialog a točítko průběhu opět zmizí. Podrobné popisování případu úspěchu zatím vynechám, protože v tomto případě ještě potřebujete někam přejít:

private async void OnSignInAttempted(){ ProgressBar signInProgress = FindViewById<ProgressBar>(Resource.Id.signin_progress); signInProgress.Visibility = ViewStates.Visible; AuthorizationResult authorizationResult = await authorizationProvider.SignInAsync(); if (!string.IsNullOrWhiteSpace(authorizationResult.AccessToken) && authorizationResult.IsAuthorized) { // Placeholder: Success case } else { // Display an error to the user AlertDialog authorizationErrorDialog = new AlertDialog.Builder(this) .SetTitle("Error!") .SetMessage("We were unable to authorize you.") .Create(); authorizationErrorDialog.Show(); signInProgress.Visibility = ViewStates.Gone; }}

Když je uživatel ověřen, měli byste ho přesměrovat na další stránku vašeho prostředí. Pokud si vzpomínáte, dříve byla každá stránka reprezentována aktivitou, a proto je třeba nyní vytvořit novou.

Pro začátek je třeba ve složce „Resources -> layout“ vytvořit nový soubor rozvržení aktivity „activity_dashboard.axml“. Nejsnadněji to provedete tak, že v kontextové nabídce přejdete na možnost Nová položka… a vyberete šablonu „Rozložení Android“. V rámci nového souboru rozvržení přidejte jednoduchou komponentu TextView, která bude zobrazovat text takto:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <TextView android:id="@+id/welcome_message" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /></LinearLayout>

V tomto úryvku máte komponentu TextView s odkazovatelným ID, která je vycentrovaná uprostřed stránky a z níž se zobrazí uvítací zpráva. Dále vytvořte odpovídající třídu aktivity „DashboardActivity“ pomocí možnosti „New Item…“ v kontextové nabídce z projektu v průzkumníku řešení a výběrem šablony „Activity“. Abyste tuto třídu propojili s jejím souborem rozvržení, musíte ve vygenerované metodě OnCreate() (pod zděděným voláním základní metody) zavolat funkci SetContentView:

SetContentView(Resource.Layout.activity_dashboard);

Pro personalizaci uvítací zprávy budete chtít nové aktivitě předat jméno uživatele. Pokud si vzpomínáte na dřívější dobu, nejlepší způsob, jak to udělat, byl pomocí Extras na záměru a vytvořili jste třídu Extensions, která to zvládne. Stejně jako dříve přidejte do souboru IntentExtensions.cs, který jste vytvořili výše, nové metody pro ‚Put‘ a ‚Get‘ extra ‚name‘:

private const string NameKey = "Name";public static void PutNameExtra(this Intent intent, string name){ intent.PutExtra(NameKey, name);}public static string GetNameExtra(this Intent intent){ return intent.GetStringExtra(NameKey);}

Nyní pomocí této rozšířené funkce po volání SetContentView, které jste provedli v metodě OnCreate(), načtěte jméno uživatele a vhodně nastavte text komponenty TextView:

string name = Intent.GetNameExtra();TextView welcomeMessage = FindViewById<TextView>(Resource.Id.welcome_message);welcomeMessage.Text = Resources.GetString(Resource.String.welcome_message_format, name);

V tomto výpisu se po načtení instance TextView nastaví její hodnota na vaši uvítací zprávu, kterou vytvoříte pomocí ekvivalentu string.Format() v systému Android Resources.

Tímto je vaše činnost na ovládacím panelu dokončena a nyní je třeba ji zavolat. V zástupci pro případ úspěchu, který jsem nechal otevřený z metody OnSignInAttempted, toho dosáhnete přidáním následujícího kódu:

JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();JwtSecurityToken jsonToken = tokenHandler.ReadJwtToken(authorizationResult.IdentityToken);IEnumerable<Claim> claims = jsonToken?.Payload?.Claims;string name = claims?.FirstOrDefault(x => x.Type == "name")?.Value;Intent dashboardIntent = new Intent(this, typeof(DashboardActivity));dashboardIntent.PutNameExtra(name);StartActivity(dashboardIntent);Finish();

První blok načte token a získá jméno uživatele (pokud existuje). Ve druhém se vytvoří nový Intent pro aktivitu dashboard, do tohoto Intent se uloží jméno uživatele pomocí vaší výše definované rozšiřující metody a poté se aktivita spustí (tj. přejde se na ni). Aby uživatel nemohl poté přejít zpět na tuto stránku, končí kód voláním metody Finish().

Spustit aplikaci pro Android

Nyní je čas spustit aplikaci pomocí zvoleného zařízení!!!

Pokud ladíte pomocí emulátoru, mělo by to být tak jednoduché, jako stisknout klávesu F5, čímž se nejprve otevře a načte emulátor a poté se do něj nasadí kód. Jako poznámku na okraj je třeba uvést, že emulátor nemusíte mezi pokusy o spuštění/debugování zavírat, protože stačí aplikaci znovu nasadit.

Pokud ladíte pomocí zařízení, které ještě nebylo k tomuto účelu použito, budete muset zařízení nejprve nastavit. To provedete tak, že povolíte možnosti pro vývojáře a v rámci nové nabídky zapnete „Ladění Androidu“ v záhlaví „Ladění“. Poté stačí zařízení připojit, přijmout dialogové okno na zařízení potvrzující, že se jedná o bezpečné připojení pro ladění, a měli byste být schopni nasadit a spustit aplikaci pomocí F5. Všimněte si, že fyzická zařízení mají vyšší prioritu než emulátor a po připojení se na něj přepnou jako na výchozí možnost ladění.

Po nasazení a načtení aplikace vás přivítá výchozí šablona jedné stránky. Otevřete nabídku v pravém horním rohu a přihlaste se, a jakmile zadáte své údaje, měli byste se vrátit na tuto stránku s rotujícím ukazatelem průběhu, než budete automaticky odesláni na stránku ovládacího panelu s uvítací zprávou:

Dozvíte se více o Xamarinu, OpenID Connect a bezpečném ověřování

Pokud jste postupovali podle všech těchto kroků, máte nyní základní aplikaci pro Android vytvořenou pomocí Xamarinu.Android s plně funkčním ověřováním uživatelů založeným na OpenID a službě Okta. Odtud můžete snadno rozšířit aktivitu ovládacího panelu a implementovat své funkce.

Chcete-li si prohlédnout celý kód z tohoto příspěvku, přejděte na naši stránku GitHub.

Pokud ve vás tento návod vzbudil chuť k vývoji pro Xamarin a chtěli byste se dozvědět více, pak bych vám rozhodně doporučil podívat se na tyto další skvělé články:

  • Přidejte správu identit do své aplikace pro Android
  • Přidejte ověřování do své aplikace Xamarin.Forms pomocí OpenID Connect
  • Vytvořte aplikaci pro iOS a Android pomocí Xamarinu

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.