Compartilhar via


Xamarin.Essentials: Autenticador da Web

A classe WebAuthenticator permite que você inicie fluxos baseados em navegador que escutam um retorno de chamada para uma URL específica registrada no aplicativo.

Visão geral

Muitos aplicativos exigem a adição de autenticação de usuário, e isso geralmente significa permitir que os usuários entrem em suas contas existentes da Microsoft, Facebook, Google e agora Apple Sign In.

A Biblioteca de Autenticação da Microsoft (MSAL) fornece uma excelente solução pronta para adicionar autenticação ao seu aplicativo. Há até mesmo suporte para aplicativos Xamarin em seu pacote NuGet cliente.

Se você estiver interessado em usar seu próprio serviço Web para autenticação, é possível usar o WebAuthenticator para implementar a funcionalidade do lado do cliente.

Por que usar um back-end de servidor?

Muitos provedores de autenticação passaram a oferecer apenas fluxos de autenticação explícitos ou bidirecionais para garantir melhor segurança. Isso significa que você precisará de um "segredo do cliente" do provedor para concluir o fluxo de autenticação. Infelizmente, os aplicativos móveis não são um ótimo lugar para armazenar segredos e qualquer coisa armazenada no código, binários ou outros de um aplicativo móvel geralmente é considerada insegura.

A prática recomendada aqui é usar um back-end da Web como uma camada intermediária entre seu aplicativo móvel e o provedor de autenticação.

Importante

É altamente recomendável não usar bibliotecas e padrões de autenticação somente móveis mais antigos que não aproveitam um back-end da Web no fluxo de autenticação devido à falta de segurança inerente para armazenar segredos do cliente.

Introdução

Para começar a usar essa API, leia o guia de introdução para Xamarin.Essentials garantir que a biblioteca esteja instalada e configurada corretamente em seus projetos.

Para acessar a funcionalidade WebAuthenticator, é necessária a seguinte configuração específica da plataforma.

O Android requer uma configuração de Filtro de Intenção para lidar com seu URI de retorno de chamada. Isso é feito facilmente subclassificando a WebAuthenticatorCallbackActivity classe:

const string CALLBACK_SCHEME = "myapp";

[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
    Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
    DataScheme = CALLBACK_SCHEME)]
public class WebAuthenticationCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
{
}

Se a versão do Android de destino do projeto estiver definida como Android 11 (API R 30), você deverá atualizar o manifesto do Android com consultas usadas com os novos requisitos de visibilidade do pacote.

Abra o arquivo AndroidManifest.xml na pasta Propriedades e adicione o seguinte dentro do nó do manifesto:

<queries>
    <intent>
        <action android:name="android.support.customtabs.action.CustomTabsService" />
    </intent>
</queries>

Usando WebAuthenticator

Adicione uma referência a Xamarin.Essentials em sua classe:

using Xamarin.Essentials;

A API consiste principalmente em um único método AuthenticateAsync que usa dois parâmetros: a url que deve ser usada para iniciar o fluxo do navegador da Web e o Uri para o qual você espera que o fluxo chame de volta e que seu aplicativo está registrado para ser capaz de manipular.

O resultado é um WebAuthenticatorResult que inclui todos os parâmetros de consulta analisados do URI de retorno de chamada:

var authResult = await WebAuthenticator.AuthenticateAsync(
        new Uri("https://mysite.com/mobileauth/Microsoft"),
        new Uri("myapp://"));

var accessToken = authResult?.AccessToken;

A API WebAuthenticator se encarrega de lançar a url no navegador e aguardar até que o retorno de chamada seja recebido:

Fluxo típico de autenticação da Web

Se o usuário cancelar o fluxo a qualquer momento, um TaskCanceledException será lançado.

Sessão de autenticação privada

O iOS 13 introduziu uma API efêmera do navegador da web para que os desenvolvedores iniciassem a sessão de autenticação como privada. Isso permite que os desenvolvedores solicitem que nenhum cookie compartilhado ou dados de navegação estejam disponíveis entre as sessões de autenticação e que haja uma nova sessão de login a cada vez. Isso está disponível através do novo WebAuthenticatorOptions que foi introduzido no Xamarin.Essentials 1.7 para iOS.

var url = new Uri("https://mysite.com/mobileauth/Microsoft");
var callbackUrl = new Uri("myapp://");
var authResult = await WebAuthenticator.AuthenticateAsync(new WebAuthenticatorOptions
    {
        Url = url,
        CallbackUrl = callbackUrl,
        PrefersEphemeralWebBrowserSession = true
    });

Diferenças de plataforma

As guias personalizadas são usadas sempre que disponíveis, caso contrário, uma intenção é iniciada para o URL.

Login da Apple

De acordo com as diretrizes de revisão da Apple, se o seu aplicativo usar qualquer serviço de login social para autenticação, ele também deverá oferecer o Apple Sign In como uma opção.

Para adicionar o Apple Sign In aos seus aplicativos, primeiro você precisa configurar seu aplicativo para usar o Apple Sign In.

Para iOS 13 e superior, você deve chamar o AppleSignInAuthenticator.AuthenticateAsync() método. Isso usará as APIs de login nativas da Apple para que seus usuários tenham a melhor experiência possível nesses dispositivos. Você pode escrever seu código compartilhado para usar a API correta em runtime como este:

var scheme = "..."; // Apple, Microsoft, Google, Facebook, etc.
WebAuthenticatorResult r = null;

if (scheme.Equals("Apple")
    && DeviceInfo.Platform == DevicePlatform.iOS
    && DeviceInfo.Version.Major >= 13)
{
    // Use Native Apple Sign In API's
    r = await AppleSignInAuthenticator.AuthenticateAsync();
}
else
{
    // Web Authentication flow
    var authUrl = new Uri(authenticationUrl + scheme);
    var callbackUrl = new Uri("xamarinessentials://");

    r = await WebAuthenticator.AuthenticateAsync(authUrl, callbackUrl);
}

var authToken = string.Empty;
if (r.Properties.TryGetValue("name", out var name) && !string.IsNullOrEmpty(name))
    authToken += $"Name: {name}{Environment.NewLine}";
if (r.Properties.TryGetValue("email", out var email) && !string.IsNullOrEmpty(email))
    authToken += $"Email: {email}{Environment.NewLine}";

// Note that Apple Sign In has an IdToken and not an AccessToken
authToken += r?.AccessToken ?? r?.IdToken;

Dica

Para dispositivos não iOS 13, isso iniciará o fluxo de autenticação da Web, que também pode ser usado para habilitar o Logon da Apple em seus dispositivos Android e UWP. Você pode entrar em sua conta iCloud em seu simulador iOS para testar o Apple Sign In.


Back-end do servidor principal ASP.NET

É possível usar a WebAuthenticator API com qualquer serviço de back-end da Web. Para usá-lo com um aplicativo principal ASP.NET, primeiro você precisa configurar o aplicativo Web com as seguintes etapas:

  1. Configure os provedores de autenticação social externa desejados em um aplicativo Web ASP.NET Core.
  2. Defina o Esquema de Autenticação Padrão como CookieAuthenticationDefaults.AuthenticationScheme em sua .AddAuthentication() chamada.
  3. Use .AddCookie() em sua chamada Startup.cs .AddAuthentication() .
  4. Todos os provedores devem ser configurados com .SaveTokens = true;.
services.AddAuthentication(o =>
    {
        o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddFacebook(fb =>
    {
        fb.AppId = Configuration["FacebookAppId"];
        fb.AppSecret = Configuration["FacebookAppSecret"];
        fb.SaveTokens = true;
    });

Dica

Se desejar incluir o Apple Sign In, você pode usar o pacote AspNet.Security.OAuth.Apple NuGet. Você pode exibir o exemplo completo de Startup.cs no repositório GitHub do Essentials.

Adicione um controlador de autenticação móvel personalizado

Com um fluxo de autenticação móvel, geralmente é desejável iniciar o fluxo diretamente para um provedor que o usuário escolheu (por exemplo, clicando em um botão "Microsoft" na tela de entrada do aplicativo). Também é importante poder retornar informações relevantes para seu aplicativo em um URI de retorno de chamada específico para encerrar o fluxo de autenticação.

Para conseguir isso, use um controlador de API personalizado:

[Route("mobileauth")]
[ApiController]
public class AuthController : ControllerBase
{
    const string callbackScheme = "myapp";

    [HttpGet("{scheme}")] // eg: Microsoft, Facebook, Apple, etc
    public async Task Get([FromRoute]string scheme)
    {
        // 1. Initiate authentication flow with the scheme (provider)
        // 2. When the provider calls back to this URL
        //    a. Parse out the result
        //    b. Build the app callback URL
        //    c. Redirect back to the app
    }
}

A finalidade desse controlador é inferir o esquema (provedor) que o aplicativo está solicitando e iniciar o fluxo de autenticação com o provedor social. Quando o provedor retorna a chamada para o back-end da Web, o controlador analisa o resultado e redireciona para o URI de retorno de chamada do aplicativo com parâmetros.

Às vezes, talvez você queira retornar dados como o provedor access_token de volta ao aplicativo, o que pode ser feito por meio dos parâmetros de consulta do URI de retorno de chamada. Ou você pode criar sua própria identidade em seu servidor e devolver seu próprio token ao aplicativo. O que e como você faz essa parte depende de você!

Confira o exemplo completo do controlador no repositório do Essentials.

Observação

O exemplo acima demonstra como retornar o Token de Acesso do provedor de autenticação de terceiros (ou seja: OAuth). Para obter um token que você pode usar para autorizar solicitações da web para o próprio back-end da web, você deve criar seu próprio token em seu aplicativo da web e devolvê-lo. A Visão geral da autenticação do ASP.NET Core contém mais informações sobre cenários de autenticação avançada no ASP.NET Core.


API