Back-End

18 mai, 2018

ASP .NET Web API – Implementando a segurança via Tokens – Parte 02

Publicidade

Continuando o artigo anterior, vamos iniciar a criação da Web API e a implementação da segurança em uma Web API usando Tokens.

Para isso, teremos que realizar as seguintes tarefas:

  • Criar uma Web API com um serviço REST usando o Entity Framework 6.2
  • Definir a autenticação de usuários
  • Transformar a nossa Web API em uma aplicação OWIN
  • Ativar o CORS na Web API via OWIN
  • Ativar a geração de Tokens via OAuth
  • Testar os serviços usando o Postman

Vou criar uma Web API para expor os serviços REST e realizar as operações CRUD com informações de funcionários que estão armazenados na tabela Funcionarios do banco de dados Estudo.mdf no SQL Server.

Além disso, temos uma tabela Usuarios que usaremos para autenticar os usuários para acessar nossa Web API. Abaixo, temos a estrutura das tabelas Funcionarios e Usuarios:

A seguir, vamos definir no projeto as classes Funcionario e Usuario que serão o nosso modelo de domínio, e depois criar o Controlador com os métodos da Web API.

Criando a Web API no VS 2017 Community

  • Abra o VS Community 2017 e clique em “New Project”
  • Selecione a linguagem Visual C# -> Web -> ASP .NET Web Application(.NET Framework)
  • Informe o nome FuncionariosAPIService e clique no botão “OK”
  • A seguir, selecione o template Web API, sem autenticação nem hospedagem na nuvem e clique em OK

Incluindo a referência ao Entity Framework

Vamos incluir o pacote do EF 6.2 no projeto via Nuget: (Menu Tools->Manage Nuget Packages for Solution).

Clique em “Browse”, selecione o pacote e clique em “Install”:

Criando o modelo de domínio e a classe de Contexto

Na pasta Models do projeto vamos criar as classes Funcionario e Usuario que representam o nosso modelo de domínio e que serão mapeadas para as tabelas Funcionarios e Usuarios via EF.

Abaixo, vemos o código das classes:

Funcionario

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace FuncionariosAPIService.Models
{
    [Table("Funcionarios")]
    public class Funcionario
    {
        [Key]
        public int FuncionarioId { get; set; }
        public string Nome { get; set; }
        public string Email { get; set; }
        public string Sexo { get; set; }
        public int Salario { get; set; }
        public string Setor { get; set; }
    }
}

Usuario

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace FuncionariosAPIService.Models
{
    [Table("Usuarios")]
    public class Usuario
    {
        [Key]
        public int UsuarioId { get; set; }
        public string Login { get; set; }
        public string Senha { get; set; }
        public string Nome { get; set; }
        public int Email { get; set; }
    }
}

A seguir, temos o código da classe de contexto FuncionarioDbContext que faz o mapeamento das entidades com as tabelas usando o Entity Framework: FuncionarioDbContext.

using System.Data.Entity;
namespace FuncionariosAPIService.Models
{
    public class FuncionarioDBContext : DbContext
    {
        public FuncionarioDBContext() : base("name=FuncionarioDBContext")
        {}
        public virtual DbSet<Funcionario> Funcionarios { get; set; }
        public virtual DbSet<Usuario> Usuarios { get; set; }
    }
}

Definindo a string de conexão no arquivo web.config

Precisamos definir a string de conexão no arquivo web.config para informar ao EF onde esta no banco de dados. Abra o arquivo Web.Config do projeto e inclua o código abaixo:

...
<connectionStrings>
   <add name="FuncionarioDbContext" connectionString="Data Source=.\;Initial Catalog=Estudo;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
...

Observe que o nome da string de conexão é o mesmo que o nome da nossa classe de Contexto: FuncionarioDbContext.

Criando o controlador FuncionariosController

Vamos criar o controlador FuncionariosController na pasta Controllers, onde vamos definir os métodos Action para exibir e realizar as operações CRUD. Clique com o botão direito sobre a pasta “Controllers” , depois em “Add” e em seguida, em “Controller”;

Selecione a opção “Web API 2 Controller with actions, using Entity Framework” do Scaffolding, clique em “Add“, informe o nome FuncionariosController e clique em “Add”;

Teremos o seguinte código gerado pelo Scaffolding para nossa Web API:

using FuncionariosAPIService.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.Http.Description;
namespace FuncionariosAPIService.Controllers
{
    public class FuncionariosController : ApiController
    {
        private FuncionarioDBContext db = new FuncionarioDBContext();
        // GET: api/Funcionarios      
        public IQueryable<Funcionario> GetFuncionarios()
        {
            return db.Funcionarios;
        }
        // GET: api/Funcionarios/5
        [ResponseType(typeof(Funcionario))]
        public IHttpActionResult GetFuncionario(int id)
        {
            Funcionario funcionario = db.Funcionarios.Find(id);
            if (funcionario == null)
            {
                return NotFound();
            }
            return Ok(funcionario);
        }
        // PUT: api/Funcionarios/5
        [ResponseType(typeof(void))]
        public IHttpActionResult PutFuncionario(int id, Funcionario funcionario)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            if (id != funcionario.FuncionarioId)
            {
                return BadRequest();
            }
            db.Entry(funcionario).State = EntityState.Modified;
            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!FuncionarioExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return StatusCode(HttpStatusCode.NoContent);
        }
        // POST: api/Funcionarios
        [ResponseType(typeof(Funcionario))]
        public IHttpActionResult PostFuncionario(Funcionario funcionario)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            db.Funcionarios.Add(funcionario);
            db.SaveChanges();
            return CreatedAtRoute("DefaultApi", new { id = funcionario.FuncionarioId }, funcionario);
        }
        // DELETE: api/Funcionarios/5
        [ResponseType(typeof(Funcionario))]
        public IHttpActionResult DeleteFuncionario(int id)
        {
            Funcionario funcionario = db.Funcionarios.Find(id);
            if (funcionario == null)
            {
                return NotFound();
            }
            db.Funcionarios.Remove(funcionario);
            db.SaveChanges();
            return Ok(funcionario);
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
        private bool FuncionarioExists(int id)
        {
            return db.Funcionarios.Count(e => e.FuncionarioId == id) > 0;
        }
    }
}

E pronto, temos assim a nossa Web API que vai expor os serviços para realizar o CRUD nos funcionários, já pronta para ser usada.

Criando a autenticação do usuário para acessar a Web API

Vamos criar uma classe chamada FuncionariosSeguranca, onde vamos definir uma autenticação bem simples para o usuário que desejar acessar os serviços da nossa Web API.

Vamos criar uma pasta Services no projeto, e nesta pasta inclua a classe “FuncionariosSeguranca” com o seguinte código:

using FuncionariosAPIService.Models;
using System;
using System.Linq;
namespace FuncionariosAPIService.Services
{
    public class FuncionariosSeguranca
    {
        public static bool Login(string login, string senha)
        {
            using (FuncionarioDBContext entities = new FuncionarioDBContext())
            {
                return entities.Usuarios.Any(user =>
               user.Login.Equals(login, StringComparison.OrdinalIgnoreCase)
               && user.Senha == senha);
            }
        }
    }
}

O código é bem simples e serve apenas para verificar o nome e senha do usuário na tabela Usuarios.

Na próxima parte do artigo veremos como implementar a proteção de uma Web API usando a implementação via Token.