Como usar o SDK do ASP.NET Framework para Aplicativos Móveis do Azure

Este tópico mostra como usar o SDK do servidor back-end .NET nos principais cenários de Aplicativos Móveis do Serviço de Aplicativo do Azure. O SDK de Aplicativos Móveis do Azure ajuda você a trabalhar com clientes móveis de seu aplicativo ASP.NET.

Aviso

Este artigo aborda informações para a versão da biblioteca v4.2.0, que é substituída pela biblioteca v5.0.0. Para obter as informações mais atualizadas, consulte o artigo para obter a versão mais recente

Criar um back-end do Azure Mobile Apps ASP.NET Framework

Você pode criar um aplicativo ASP.NET Framework usando o Visual Studio 2019.

  • Escolha o modelo ASP.NET Aplicativo Web (.NET Framework ). Se você estiver tendo problemas para localizar esse modelo, selecione C#, Todas as plataformas e Web.
  • Depois de selecionar um nome e um local para o aplicativo, selecione o modelo de projeto da API Web. A coleção correta de serviços básicos para seu aplicativo será instalada.

Baixe e inicialize o SDK

O SDK está disponível no NuGet.org e fornece a funcionalidade básica necessária para começar a usar os Aplicativos Móveis do Azure. Para instalar o pacote:

  1. Clique com o botão direito do mouse no projeto e selecione Gerenciar pacotes NuGet....
  2. No separador Procurar, introduza Microsoft.Azure.Mobile.Server na caixa de pesquisa e, em seguida, prima Enter.
  3. Selecione o Microsoft.Azure.Mobile.Server.Quickstart pacote.
  4. Clique em Install (Instalar).
  5. Siga as instruções para concluir a instalação.

Repita o processo para instalar Microsoft.Owin.Host.SystemWeb também.

Nota

Não atualize os pacotes que são usados como dependências, como Newtonsoft.JSON ou System.IdentityModel.Jwt. As APIs desses pacotes foram, em muitos casos, alteradas e agora são incompatíveis com os Aplicativos Móveis do Azure para ASP.NET Framework.

Inicializar o projeto do servidor

Um projeto de servidor de Aplicativos Móveis do Azure é inicializado de forma semelhante a outros projetos do ASP.NET Framework; incluindo uma classe OWIN Startup. Para adicionar uma classe OWIN Startup:

  1. Clique com o botão direito do mouse no projeto e selecione Adicionar>Novo Item

  2. Selecione Web>General e, em seguida, selecione o modelo de classe OWIN Startup.

  3. Digite o nome como o nome Startup.cs da inicialização.

  4. O conteúdo do Startup.cs arquivo deve ser semelhante ao seguinte código:

    using Microsoft.Azure.Mobile.Server.Config;
    using Microsoft.Owin;
    using Owin;
    using System.Web.Http;
    
    [assembly: OwinStartup(typeof(WebApplication1.Startup))]
    namespace WebApplication1
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                HttpConfiguration config = new HttpConfiguration();
                new MobileAppConfiguration()
                    // no added features
                    .ApplyTo(config);
                app.UseWebApi(config);
            }
        }
    }
    

    O namespace , e o OwinStartupnome da classe serão diferentes, dependendo do seu projeto. Especificamente, você deve substituir o Configuration() conteúdo do método e ajustar as using diretivas de acordo.

Para habilitar recursos individuais, você deve chamar métodos de extensão no objeto MobileAppConfiguration antes de chamar ApplyTo. Por exemplo, o código a seguir adiciona as rotas padrão a todos os controladores de API que têm o atributo [MobileAppController] durante a inicialização:

new MobileAppConfiguration()
    .MapApiControllers()
    .ApplyTo(config);

A configuração a seguir é considerada um uso "normal" que permite que controladores de tabela e API usando o Entity Framework acessem um serviço SQL.

new MobileAppConfiguration()
    .AddMobileAppHomeController()
    .MapApiControllers()
    .AddTables(
        new MobileAppTableConfiguration()
            .MapTableControllers()
            .AddEntityFramework()
    )
    .MapLegacyCrossDomainController()
    .ApplyTo(config);

Os métodos de extensão utilizados são:

  • AddMobileAppHomeController() fornece a home page padrão dos Aplicativos Móveis do Azure.
  • MapApiControllers() fornece recursos de API personalizados para controladores WebAPI decorados com o [MobileAppController] atributo.
  • AddTables() Fornece um mapeamento dos pontos de extremidade para controladores de /tables tabela.
  • AddTablesWithEntityFramework() é uma abreviação para mapear os /tables pontos de extremidade usando controladores baseados no Entity Framework.
  • MapLegacyCrossDomainController() fornece cabeçalhos CORS padrão para o desenvolvimento local.

Extensões SDK

Os seguintes pacotes de extensão baseados em NuGet fornecem vários recursos móveis que podem ser usados pelo seu aplicativo. Você habilita extensões durante a inicialização usando o objeto MobileAppConfiguration .

  • Microsoft.Azure.Mobile.Server.Quickstart Suporta a configuração básica de Aplicativos Móveis. Adicionado à configuração chamando o método de extensão UseDefaultConfiguration durante a inicialização. Esta extensão inclui as seguintes extensões: Notificações, Autenticação, Entidade, Tabelas, Domínios cruzados e pacotes Home.
  • Microsoft.Azure.Mobile.Server.Home Implementa a página padrão Este aplicativo móvel está ativo e em execução para a raiz do site. Adicione à configuração chamando o método de extensão AddMobileAppHomeController .
  • Microsoft.Azure.Mobile.Server.Tables inclui classes para trabalhar com dados e configura o pipeline de dados. Adicione à configuração chamando o método de extensão AddTables .
  • Microsoft.Azure.Mobile.Server.Entity Permite que o Entity Framework acesse dados no Banco de Dados SQL. Adicione à configuração chamando o método de extensão AddTablesWithEntityFramework .
  • Microsoft.Azure.Mobile.Server.Authentication Habilita a autenticação e configura o middleware OWIN usado para validar tokens. Adicione à configuração chamando AddAppServiceAuthentication e IAppBuilder.Métodos de extensão UseAppServiceAuthentication.
  • Microsoft.Azure.Mobile.Server.Notifications Habilita notificações por push e define um ponto de extremidade de registro por push. Adicione à configuração chamando o método de extensão AddPushNotifications .
  • Microsoft.Azure.Mobile.Server.CrossDomain Cria um controlador que fornece dados para navegadores da Web herdados a partir do seu aplicativo móvel. Adicione à configuração chamando o método de extensão MapLegacyCrossDomainController .
  • Microsoft.Azure.Mobile.Server.Login Fornece o AppServiceLoginHandler.CreateToken() método, que é um método estático usado durante cenários de autenticação personalizada.

Publicar o projeto do servidor

Esta seção mostra como publicar seu projeto de back-end .NET do Visual Studio. Existem outros métodos pelos quais você pode publicar seu aplicativo. Para obter mais informações, consulte a documentação do Serviço de Aplicativo do Azure.

  1. No Visual Studio, recrie o projeto para restaurar pacotes NuGet.
  2. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto, clique em Publicar.
  3. Se você não publicou este projeto antes, você configurará a publicação.
    • Selecione Azure para o destino.
    • Selecione Serviço de Aplicativo do Azure (Windows) para o destino específico.
    • Selecione a instância do serviço de aplicativo na qual você deseja implantar. Se você não tiver um, use o + para criar um.
    • Clique em Concluir.
  4. Se você não tiver vinculado um banco de dados SQL antes, clique em Configurar ao lado do Banco de Dados SQL.
    • Selecione o Banco de Dados SQL do Azure
    • Selecione a base de dados. Se você não tiver um ou quiser usar um diferente, clique no + botão para criar um novo banco de dados e servidor.
    • Insira MS_TableConnectionString como o nome da cadeia de conexão do banco de dados. Preencha o nome de utilizador e a palavra-passe nas caixas fornecidas.
    • Clique em Concluir
  5. Clique em Publicar

Leva algum tempo para publicar no Azure. Para obter mais informações, consulte a documentação do Visual Studio.

Definir um controlador de tabela

Defina um controlador de tabela para expor uma tabela SQL a clientes móveis. A configuração de um controlador de tabela requer três etapas:

  1. Crie uma classe DTO (Data Transfer Object).
  2. Configure uma referência de tabela na classe Mobile DbContext.
  3. Crie um controlador de tabela.

Um objeto de transferência de dados (DTO) é um objeto C# simples que herda de EntityData. Por exemplo:

public class TodoItem : EntityData
{
    public string Text { get; set; }
    public bool Complete {get; set;}
}

O DTO é usado para definir a tabela dentro do banco de dados SQL. Para criar a entrada do banco de dados, adicione uma DbSet<> propriedade à DbContext que você está usando:

public class MobileServiceContext : DbContext
{
    private const string connectionStringName = "Name=MS_TableConnectionString";

    public MobileServiceContext() : base(connectionStringName)
    {

    }

    public DbSet<TodoItem> TodoItems { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Add(
            new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
                "ServiceColumnTable", (property, attributes) => attributes.Single().ColumnType.ToString()));
    }
}

Finalmente, crie um novo controlador:

  1. Clique com o botão direito do rato na Controllers pasta.

  2. Selecione Web API Web API>2 Controller - Vazio

  3. Insira um nome para o controlador.

  4. Substitua o conteúdo do novo controlador pelo seguinte código:

    public class TodoItemController : TableController<TodoItem>
    {
        protected override void Initialize(HttpControllerContext controllerContext)
        {
            base.Initialize(controllerContext);
            ZUMOAPPNAMEContext context = new ZUMOAPPNAMEContext();
            DomainManager = new EntityDomainManager<TodoItem>(context, Request);
        }
    
        // GET tables/TodoItem
        public IQueryable<TodoItem> GetAllTodoItems()
        {
            return Query();
        }
    
        // GET tables/TodoItem/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public SingleResult<TodoItem> GetTodoItem(string id)
        {
            return Lookup(id);
        }
    
        // PATCH tables/TodoItem/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public Task<TodoItem> PatchTodoItem(string id, Delta<TodoItem> patch)
        {
            return UpdateAsync(id, patch);
        }
    
        // POST tables/TodoItem
        public async Task<IHttpActionResult> PostTodoItem(TodoItem item)
        {
            TodoItem current = await InsertAsync(item);
            return CreatedAtRoute("Tables", new { id = current.Id }, current);
        }
    
        // DELETE tables/TodoItem/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public Task DeleteTodoItem(string id)
        {
            return DeleteAsync(id);
        }
    }
    

Ajustar o tamanho da paginação da tabela

Por padrão, os Aplicativos Móveis do Azure retornam 50 registros por solicitação. A paginação garante que o cliente não amarre seu thread de interface do usuário nem o servidor por muito tempo, garantindo uma boa experiência do usuário. Para alterar o tamanho da paginação da tabela, aumente o "tamanho da consulta permitido" do lado do servidor e o tamanho da página do lado do cliente O "tamanho da consulta permitido" do lado do servidor é ajustado usando o EnableQuery atributo:

[EnableQuery(PageSize = 500)]

Verifique se o PageSize é igual ou maior do que o tamanho solicitado pelo cliente. Consulte a documentação específica do cliente HOWTO para obter detalhes sobre como alterar o tamanho da página do cliente.

Definir um controlador de API personalizado

O controlador de API personalizado fornece a funcionalidade mais básica para o back-end do seu aplicativo móvel, expondo um ponto de extremidade. Você pode registrar um controlador de API específico para dispositivos móveis usando o atributo [MobileAppController]. O MobileAppController atributo registra a rota, configura o serializador JSON de Aplicativos Móveis e ativa a verificação de versão do cliente.

O conteúdo do controlador de API personalizada é:

[MobileAppController]
public class CustomAPIController : ApiController
{
    // Content here
}

Uma vez configurado com o MobileAppController atributo, você pode definir a API personalizada da mesma forma que qualquer outra API da Web.

Trabalhar com autenticação

Os Aplicativos Móveis do Azure usam a Autenticação/Autorização do Serviço de Aplicativo para proteger seu back-end móvel. Esta seção mostra como executar as seguintes tarefas relacionadas à autenticação em seu projeto de servidor back-end .NET:

Adicionar autenticação a um projeto de servidor

Você pode adicionar autenticação ao seu projeto de servidor estendendo o objeto MobileAppConfiguration e configurando o middleware OWIN.

  1. No Visual Studio, instale o pacote Microsoft.Azure.Mobile.Server.Authentication .

  2. Startup.cs No arquivo de projeto, adicione a seguinte linha de código no início do método Configuration:

    app.UseAppServiceAuthentication(config);
    

    Esse componente de middleware OWIN valida tokens emitidos pelo gateway do Serviço de Aplicativo associado.

  3. Adicione o atributo a qualquer controlador ou método que exija [Authorize] autenticação.

Usar autenticação personalizada para seu aplicativo

Importante

Para habilitar a autenticação personalizada, você deve primeiro habilitar a Autenticação do Serviço de Aplicativo sem selecionar um provedor para seu Serviço de Aplicativo no portal do Azure. Isso habilitará a WEBSITE_AUTH_SIGNING_KEY variável de ambiente quando hospedada.

Se você não deseja usar um dos provedores de Autenticação/Autorização do Serviço de Aplicativo, você pode implementar seu próprio sistema de login. Instale o pacote Microsoft.Azure.Mobile.Server.Login para ajudar na geração de token de autenticação. Forneça seu próprio código para validar as credenciais do usuário. Por exemplo, você pode verificar senhas salgadas e com hash em um banco de dados. No exemplo abaixo, o isValidAssertion() método (definido alhures) é responsável por essas verificações.

A autenticação personalizada é exposta criando um ApiController e expondo register e login ações. O cliente deve usar uma interface do usuário personalizada para coletar as informações do usuário. As informações são então enviadas para a API com uma chamada HTTP POST padrão. Depois que o servidor valida a asserção, um token é emitido usando o AppServiceLoginHandler.CreateToken() método. O ApiController não deve usar o [MobileAppController] atributo.

Um exemplo login de ação:

public IHttpActionResult Post([FromBody] JObject assertion)
{
    if (isValidAssertion(assertion)) // user-defined function, checks against a database
    {
        JwtSecurityToken token = AppServiceLoginHandler.CreateToken(new Claim[] { new Claim(JwtRegisteredClaimNames.Sub, assertion["username"]) },
            mySigningKey,
            myAppURL,
            myAppURL,
            TimeSpan.FromHours(24) );
        return Ok(new LoginResult()
        {
            AuthenticationToken = token.RawData,
            User = new LoginResultUser() { UserId = userName.ToString() }
        });
    }
    else // user assertion was not valid
    {
        return this.Request.CreateUnauthorizedResponse();
    }
}

No exemplo anterior, LoginResult e LoginResultUser são objetos serializáveis que expõem as propriedades necessárias. O cliente espera que as respostas de login sejam retornadas como objetos JSON do formulário:

{
    "authenticationToken": "<token>",
    "user": {
        "userId": "<userId>"
    }
}

O AppServiceLoginHandler.CreateToken() método inclui uma audiência e um parâmetro emissor . Ambos os parâmetros são definidos para a URL da raiz do seu aplicativo, usando o esquema HTTPS. Da mesma forma, você deve definir secretKey como o valor da chave de assinatura do seu aplicativo. Não distribua a chave de assinatura em um cliente, pois ela pode ser usada para cunhar chaves e representar usuários. Você pode obter a chave de assinatura enquanto hospedado no Serviço de Aplicativo fazendo referência à WEBSITE_AUTH_SIGNING_KEY variável de ambiente. Se necessário em um contexto de depuração local, siga as instruções na seção Depuração local com autenticação para recuperar a chave e armazená-la como uma configuração de aplicativo.

O token emitido também pode incluir outras reivindicações e uma data de validade. Minimamente, o token emitido deve incluir uma reivindicação de assunto (sub).

Você pode oferecer suporte ao método de cliente padrão sobrecarregando a rota de loginAsync() autenticação. Se o cliente ligar client.loginAsync('custom'); para fazer login, sua rota deve ser /.auth/login/custom. Você pode definir a rota para o controlador de autenticação personalizado usando MapHttpRoute():

config.Routes.MapHttpRoute("custom", ".auth/login/custom", new { controller = "CustomAuth" });

Gorjeta

O uso da loginAsync() abordagem garante que o token de autenticação seja anexado a cada chamada subsequente ao serviço.

Recuperar informações autenticadas do usuário

Quando um usuário é autenticado pelo Serviço de Aplicativo, você pode acessar o ID de usuário atribuído e outras informações em seu código de back-end .NET. As informações do usuário podem ser usadas para tomar decisões de autorização no back-end. O código a seguir obtém o ID de usuário associado a uma solicitação:

// Get the SID of the current user.
var claimsPrincipal = this.User as ClaimsPrincipal;
string sid = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier).Value;

O SID é derivado do ID de usuário específico do provedor e é estático para um determinado usuário e provedor de login. O SID é nulo para tokens de autenticação inválidos.

O Serviço de Aplicativo também permite que você solicite declarações específicas do seu provedor de login. Cada provedor de identidade pode fornecer mais informações usando o SDK do provedor de identidade. Por exemplo, você pode usar a API do Facebook Graph para obter informações de amigos. Você pode especificar declarações que são solicitadas na folha do provedor no portal do Azure. Algumas declarações exigem mais configuração com o provedor de identidade.

O código a seguir chama o método de extensão GetAppServiceIdentityAsync para obter as credenciais de login, que incluem o token de acesso necessário para fazer solicitações na API do Facebook Graph:

// Get the credentials for the logged-in user.
var credentials = await this.User.GetAppServiceIdentityAsync<FacebookCredentials>(this.Request);

if (credentials.Provider == "Facebook")
{
    // Create a query string with the Facebook access token.
    var fbRequestUrl = "https://graph.facebook.com/me/feed?access_token="
        + credentials.AccessToken;

    // Create an HttpClient request.
    var client = new System.Net.Http.HttpClient();

    // Request the current user info from Facebook.
    var resp = await client.GetAsync(fbRequestUrl);
    resp.EnsureSuccessStatusCode();

    // Do something here with the Facebook user information.
    var fbInfo = await resp.Content.ReadAsStringAsync();
}

Adicione uma instrução using para System.Security.Principal fornecer o método de extensão GetAppServiceIdentityAsync .

Restringir o acesso a dados para usuários autorizados

Na seção anterior, mostramos como recuperar o ID de usuário de um usuário autenticado. Você pode restringir o acesso a dados e outros recursos com base nesse valor. Por exemplo, adicionar uma coluna userId a tabelas e filtrar os resultados da consulta pelo ID do usuário é uma maneira simples de limitar os dados retornados apenas a usuários autorizados. O código a seguir retorna linhas de dados somente quando o SID corresponde ao valor na coluna UserId na tabela TodoItem:

// Get the SID of the current user.
var claimsPrincipal = this.User as ClaimsPrincipal;
string sid = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier).Value;

// Only return data rows that belong to the current user.
return Query().Where(t => t.UserId == sid);

O Query() método retorna um IQueryable que pode ser manipulado pelo LINQ para manipular a filtragem.

Depurar e solucionar problemas do SDK do .NET Server

O Serviço de Aplicativo do Azure fornece várias técnicas de depuração e solução de problemas para aplicativos ASP.NET:

Registo

Você pode gravar nos logs de diagnóstico do Serviço de Aplicativo usando a gravação de rastreamento de ASP.NET padrão. Antes de gravar nos logs, você deve habilitar o diagnóstico em seu back-end de Aplicativos Móveis do Azure.

Para habilitar o diagnóstico e gravar nos logs:

  1. Siga as etapas em Habilitar log de aplicativos (Windows).

  2. Adicione a seguinte instrução using em seu arquivo de código:

    using System.Web.Http.Tracing;
    
  3. Crie um gravador de rastreamento para gravar do back-end .NET para os logs de diagnóstico, da seguinte maneira:

    ITraceWriter traceWriter = this.Configuration.Services.GetTraceWriter();
    traceWriter.Info("Hello, World");
    
  4. Republique seu projeto de servidor e acesse o back-end dos Aplicativos Móveis do Azure para executar o caminho de código com o log.

  5. Transfira e avalie os registos, conforme descrito em Ficheiros de registo do Access.

Depuração local com autenticação

Você pode executar seu aplicativo localmente para testar as alterações antes de publicá-las na nuvem. Para a maioria dos back-ends de Aplicativos Móveis do Azure, pressione F5 enquanto estiver no Visual Studio. No entanto, há algumas considerações extras ao usar a autenticação.

Você deve ter um aplicativo móvel baseado em nuvem com Autenticação/Autorização do Serviço de Aplicativo configurado, e seu cliente deve ter o ponto de extremidade na nuvem especificado como o host de logon alternativo. Consulte a documentação da plataforma do seu cliente para obter as etapas específicas necessárias.

Verifique se o back-end móvel tem Microsoft.Azure.Mobile.Server.Authentication instalado. Em seguida, na classe de inicialização OWIN do seu aplicativo, adicione o seguinte, depois MobileAppConfiguration de ter sido aplicado ao seu HttpConfiguration:

app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions()
{
    SigningKey = ConfigurationManager.AppSettings["authSigningKey"],
    ValidAudiences = new[] { ConfigurationManager.AppSettings["authAudience"] },
    ValidIssuers = new[] { ConfigurationManager.AppSettings["authIssuer"] },
    TokenHandler = config.GetAppServiceTokenHandler()
});

No exemplo anterior, você deve configurar as configurações do aplicativo authAudience e authIssuer dentro do arquivo Web.config para que cada uma seja a URL da raiz do aplicativo, usando o esquema HTTPS. Da mesma forma, você deve definir authSigningKey como o valor da chave de assinatura do seu aplicativo.

Para obter a chave de assinatura:

  1. Navegue até seu aplicativo no portal do Azure
  2. Clique em Ferramentas>Kudu>Go.
  3. No site Kudu Management, clique em Ambiente.
  4. Encontre o valor para WEBSITE_AUTH_SIGNING_KEY.

Use a chave de assinatura para o parâmetro authSigningKey na configuração do aplicativo local. Seu back-end móvel agora está equipado para validar tokens ao executar localmente, que o cliente obtém o token do ponto de extremidade baseado em nuvem.