Database Weekend 2019 – Campinas

Olá pessoal,

No último sábado 27/07 participei do Database Weekend 2019 – Campinas, evento no qual ajudei tanto na organização quanto palestrando. No total tivemos um público de 70 pessoas e duas trilhas de conteúdo sendo uma trilha de Data e outra de Dev.

Os slides utilizados na minha palestra, sobre Armazenamento de dados sem grandes custos no Azure Storage você confere logo abaixo:

E para quem quiser o código utilizados na palestra, é só baixar através desse link.

Deixo aqui também um artigo que já publiquei como referência ao conteúdo apresentado.

Abaixo uma foto da minha palestra:

Database Weekend
Database Weekend 2019

.NET Core Saturday – Campinas

Olá pessoal,

No último sábado 13/07 participei do .NET Core Saturday – Campinas, evento no qual ajudei tanto na organização quanto palestrando. No total tivemos um público de 50 pessoas.

Os slides utilizados na minha palestra, sobre Utilizando o Azure Cache for Redis com ASP.NET Core 2.2 você confere logo abaixo:

E para quem quiser os códigos utilizados na palestra, é só baixar através desses links:

Deixo aqui também três artigos que já publiquei como referência ao conteúdo apresentado.

VS 2019 Launch Local – Araraquara

Olá pessoal,

No último sábado do mês de junho (29/06) participei do VS 2019 Launch Local – Araraquara, evento no qual ajudei tanto na organização quanto palestrando. No total tivemos um público de 70 pessoas.

As inscrições do evento foram realizadas através do Sympla.

Os slides utilizados na minha palestra, sobre como Desenvolver na nuvem com o VS 2019 você confere logo abaixo:

Abaixo algumas fotos do evento.

VS 2019 Launch Local – Araraquara 01
VS 2019 Launch Local – Araraquara 02

VS 2019 Launch Local + MS Build 2019

Olá pessoal,

No último sábado dia 25/05 participei do VS 2019 Launch Local + MS Build 2019, eventos no quais ajudei tanto na organização quanto palestrando. No total tivemos um público de 60 pessoas.

Os slides utilizados na minha palestra, sobre como Desenvolver na nuvem com o VS 2019 você confere logo abaixo:

Abaixo algumas fotos do evento.

VS 2019 Launch Local + MS Build 2019
VS 2019 Launch Local + MS Build 2019

Open Source Roadshow 2019 – Piracicaba-SP

Olá pessoal,

No último sábado dia 11/05 participei do Open Source Roadshow 2019 – Piracicaba-SP, evento no qual ajudei tanto na organização quanto palestrando. As inscrições do evento foram efetuadas pelo Sympla e tivemos um publico de 50 pessoas.

Os slides utilizados na minha palestra, sobre Utilizando o Azure Cache for Redis com ASP.NET Core 2 você confere logo abaixo:

E para quem quiser os códigos utilizados na palestra, é só baixar através desses links:

Deixo aqui também três artigos que já publiquei como referência ao conteúdo apresentado.

Abaixo algumas fotos do evento.

Open source Roadshow 2019 – Piracicaba
Open source Roadshow 2019 – Piracicaba

1º Meetup .NET da Dextra

Olá pessoal,

No último sábado dia 04/05 participei do 1º Meetup .NET da Dextra 
evento no qual ajudei tanto na organização quanto palestrando sobre como Desenvolver Serverless com Azure Functions. As incrições do evento foram efetuadas pelo Sympla e tivemos um publico de 100 pessoas.

Os slides utilizados na palestra você confere logo abaixo:

E para quem quiser o código utilizado, é só baixar através desse link

Abaixo algumas fotos do evento.

1º Meetup .NET da Dextra
1º Meetup .NET da Dextra
1º Meetup .NET da Dextra
1º Meetup .NET da Dextra

Visual Studio 2019 Launch Local – Jundiaí

Olá pessoal,

No último sábado dia 06/04 participei do Visual Studio 2019 Launch Local – Jundiaí palestrando sobre como Desenvolver na nuvem utilizando o Visual Studio 2019.

Os slides utilizados na palestra você confere logo abaixo:

Também gostaria de deixar aqui, meu muito obrigado para o pessoal do Developers-BR pelo convite.

Abaixo, algumas fotos da minha palestra.

Visual Studio 2019 Launch Local – Jundiaí
Visual Studio 2019 Launch Local – Jundiaí

7Masters de Serverless

Olá pessoal,

Ontem tive o prazer de participar do 7Masters de Serverless falando sobre Azure Function e Logic Apps. Tivemos casa cheia com quase 40 pessoas.

Deixo aqui meu muito obrigado para o Pokemao pelo convite.

Abaixo alguns links a respeito de evento e dos videos da palestras (que deverá ocorrer nos próximos dias).

https://setemasters.imasters.com.br/mestres/?edition_id=3326

https://setemasters.imasters.com.br/edicoes/serverless/

7Masters de Serverless
7Masters de Serverless

Criando um servidor de identidade utilizando o Identity Server 4 e o ASP.NET Core 2 – Parte 2

Conforme vimos na primeira parte deste artigo, entendemos brevemente o conceito de como funciona o protocolo oAuth 2, o OpenID Connect e o Identity Server 4. Então, sem mais delongas, vamos para a melhor parte, que é colocar tudo isso na prática.

Show me the Code!

Primeiro vamos criar um novo projeto do tipo ASP.NET Core Web Application (File > New Project). Chamaremos ele de IdentityServer, e na tela seguinte escolheremos a opção Web Application (Model-View-Controller), conforme a figura 1, abaixo:

Identity Server 4
Figura 1

Feito isso, vamos adicionar o Identity Server4 utilizando o Nuget. Para isso, clique com o botão direito na opção Dependencies e selecione a opção Manage Nuget Packages. Em seguida, adicione o pacote do Identity Server4, conforme figura abaixo:

Identity Server 4
Figura 2

Agora, para facilitar nosso desenvolvimento, faremos o download do projeto Quickstart UI repo. Esse projeto nos dá uma interface pronta com todos os tipos de autenticação previamente desenvolvidos. Vamos agora copiar as pastas QuickStart, Views e wwwroot baixadas dentro do nosso projeto para que possamos, em seguida, iniciar o desenvolvimento do nosso servidor de identidade.

Depois de copiar todos os arquivos, poderemos deletar do nosso projeto as pastas Controllers e Models, pois não a utilizaremos mais. Com todas essas alterações feitas, seu projeto deve estar igual ao da Figura 3:

Identity Server 4
Figura 3

Agora vamos definir uma porta para que o nosso projeto execute. Para isso, botão direito em cima do projeto e clique em properties (se for Visual Studio for Mac, clique em options ao invés de properties), depois clique em build, e no campo App URL, substitua a porta pra 5000 (ou qualquer outra da sua escolha – você só precisa se lembrar dela depois), e então salve o projeto. Feito isso, vamos criar uma classe chamada Config.cs e vamos implementar nossas configurações (comentários no próprio código para melhor entendimento):

using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System.Collections.Generic;
using System.Security.Claims;

namespace IdentityServer
{
    public class Config
    {
        // Aqui vamos definir os resources que serão utilizados no nosso servidor
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email()
            };
        }

        // Aqui definimos qual Client (aplicação) que poderá acessar nosso servidor de identidade.
        public static IEnumerable<Client> GetClients()
        {
            // Credenciais da Aplicação
            return new List<Client>
            {
                // OpenID Connect
                new Client
                {
                    // O Nome ÚNICO da nossa aplicação autorizada no nosso servidor de autoridade
                    ClientId = "ericsonfApp",
                    
                    // Nome de exibição da nossa aplicação
                    ClientName = "ericsonf Application",
                    
                    //Tipo de autenticação permitida
                    AllowedGrantTypes = GrantTypes.Implicit,

                    //Url de redicionamento para quando o login for efetuado com sucesso.
                    RedirectUris = { "http://localhost:5001/signin-oidc" },

                    //Url de redirecionamento para quando o logout for efetuado com sucesso.
                    PostLogoutRedirectUris = { "http://localhost:5001/signout-callback-oidc" },

                    //Escopos permitidos dentro da aplicação
                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Email
                    }
                }
            };
        }

        // TestUser é uma classe de exemplo do proprio IdentityServer, aonde configuramos basicamente login/senha e as claims de exibição.
        public static List<TestUser> GetUsers()
        {
            return new List<TestUser>
            {
                new TestUser
                {
                    SubjectId = "1",
                    Username = "ericsonf",
                    Password = "ericsonf",

                    Claims = new List<Claim>
                    {
                        new Claim("name", "Portal ericsonf"),
                        new Claim("website", "https://ericsonf.com.br"),
                        new Claim("email", "contato@ericsonf.com")
                    }
                }
            };
        }
    }
}

O próximo passo agora é configurar o Startup.cs da nossa aplicação para que ele fique igual abaixo:

using IdentityServer4.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace IdentityServer
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            // Configuração do Identity Server In-Memory
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryClients(Config.GetClients())
                .AddTestUsers(Config.GetUsers());
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            //Habilitando o uso do Identity Server no nosso projeto
            app.UseIdentityServer();

            //Habilitando o uso de arquivos estáticos (Html, Css e etc) do nosso projeto
            app.UseStaticFiles();

            //Habilitando o uso de rota no projeto
            app.UseMvcWithDefaultRoute();
        }
    }
}

Feito isso, configuramos o nosso servidor de Identidade, e agora podemos criar uma aplicação para testarmos a nossa autenticação. Então basicamente vamos seguir os mesmos passos que fizemos anteriormente ao criar um novo projeto do tipo ASP.NET Core Web Application, porém, esse vamos chamar de ericsonfApp. Mais uma vez nossa pasta Models não será utilizada em nosso exemplo, então podemos deletá-la do nosso projeto.

Antes de começarmos a programar nossa Aplicação, vamos primeiramente configurar a porta em que a aplicação vai rodar, e seguindo os mesmos do nosso servidor de identidade, vamos alterar a porta, porém dessa vez vamos apontar para a porta 5001 (observe que no código do Config.cs, apontamos o Login e Logout da aplicação para a porta 5001 também).

Agora podemos começar a programar a nossa aplicação, então primeiramente vamos abrir o arquivo Startup.cs (comentários no próprio código para melhor entendimento):

using System.IdentityModel.Tokens.Jwt;
using IdentityServer4;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace ericsonfApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            //Exibe as claims de maneira mais "amigável"
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            //Adciona o serviço de autenticação
            services.AddAuthentication(options =>
            {
                //Nosso esquema default será baseado em cookie
                options.DefaultScheme = "Cookies";

                //Como precisamos recuperar os dados depois do login, utilizamos o OpenID Connect que por padrão utiliza o escopo do Profile
                options.DefaultChallengeScheme = "oidc";
            })
                .AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = "Cookies";
                    
                    //Aponta para o nosso servidor de autenticação
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    
                    //Nome da nossa aplicação que tentará se autenticar no nosso servidor de identidade
                    //Observe que ela possui o mesmo nome da app que liberamos no nosso servidor de identidade
                    options.ClientId = "ericsonfApp";
                    options.SaveTokens = true;
                    
                    //Adicionamos o scopo do e-mail para utilizarmos a claim de e-mail.
                    options.Scope.Add(IdentityServerConstants.StandardScopes.Email);
                });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //Habilitando o uso da autenticação do Identity Server no nosso projeto
            app.UseAuthentication();

            //Habilitando o uso de arquivos estáticos (Html, Css e etc) do nosso projeto
            app.UseStaticFiles();

            //Habilitando o uso de rota no projeto
            app.UseMvcWithDefaultRoute();
        }
    }
}

O próximo passo agora será configurarmos nosso HomeController.cs:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;

namespace MvcClient.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        //Somente será acessada se o usuário estiver logado
        [Authorize]
        public IActionResult Secure()
        {
            return View();
        }

        public async Task Logout()
        {
            //Limpa o cookie para finalizar o logout
            await HttpContext.SignOutAsync("Cookies");
            await HttpContext.SignOutAsync("oidc");
        }

        public IActionResult Error()
        {
            return View();
        }
    }
} 

E por fim, vamos criar nossa página que vai exibir os dados caso o usuário seja válido e se logue corretamente. Para isso, crie o arquivo Secure.cshml dentro da pasta Views > Home.

@{
    ViewData["Title"] = "Logon efetuado com sucesso.";
}
<h2>@ViewData["Title"]</h2>

<h3>Claims autorizadas pelo usuário</h3>

<dl>
    @foreach (var claim in User.Claims)
    {
        <dt>@claim.Type</dt>
        <dd>@claim.Value</dd>
    }
</dl> 

Feito isso vamos colocar nosso Visual Studio para executar os dois projetos simultaneamente, e vamos fazer o login com os dados de acesso que criamos no nosso servidor de identidade. Se tudo deu certo você obterá uma tela igual a figura 4 abaixo:

Identity Server 4
Figura 4

Agora é só selecionar quais informações deseja exibir e na próxima tela será exibido o resultado de ac.

Bônus

Como bônus, vou implementar um Resource customizado, pois nem sempre temos as Claims que desejamos “prontas”, então mãos a obra!

Primeiramente vamos alterar o método GetIdentityResources() que se encontra no arquivo Config.cs do projeto IdentityServer.

public static IEnumerable<IdentityResource> GetIdentityResources()
{
    var customProfile = new IdentityResource(
        name: "custom.profile",
        displayName: "Custom Profile",
        claimTypes: new[] { "customclaim" }
    );

    return new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        new IdentityResources.Email(),
        customProfile
    };
} 

Depois, vamos alterar a propriedade AllowedScopes:

AllowedScopes = {
    IdentityServerConstants.StandardScopes.OpenId,
    IdentityServerConstants.StandardScopes.Profile,
    IdentityServerConstants.StandardScopes.Email,
    "custom.profile"
} 

Agora vamos adicionar nossa Claim customizada nas Claims do usuário:

Claims = new List<Claim> {
    new Claim("name", "Portal ericsonf"),
    new Claim("website", "http://ericsonf.com.br"),
    new Claim("email", contato@ericsonf.com                                   new Claim("customclaim", "Minha claim customizada")
} 

E por ultimo, vamos abrir o arquivo Startup.cs do projeto ericsonfApp e colocar a linha abaixo logo após a inclusão do scopo do e-mail:

options.Scope.Add("custom.profile");

Executando o projeto novamente e fazendo o login corretamente, note que apareceu o nosso Resource customizado nas opções de exibição, conforme mostra a figura 5 abaixo:

Figura 5

Bom, pessoal, era isso que eu queria mostrar. Para quem quiser o código completo ele está no meu GitHub.

Muito obrigado e até a próxima!

Criando um servidor de Identidade utilizando Identity Server 4 e ASP.NET Core 2 – Parte 1

Neste artigo, pretendo mostrar como criar um servidor de identidade para autenticarmos nossas aplicações através dele.

Antes de “colocarmos a mão na massa”, vamos entender de maneira simplificada como funciona o protocolo OAuth 2, a camada OpenID Connect e por fim, o Identity Server 4 para tirarmos mais proveito desse artigo (caso desejem ir mais a fundo, deixarei o link da documentação de cada um no final desse artigo).

OAuth 2

O OAuth 2.0 é um protocolo de autorização aberto que permite que uma aplicação acesse recursos protegidos de outra aplicação em nome de um usuário sem expor sua senha.

Exemplificando o que foi dito acima, é basicamente você acessar o Medium utilizando sua conta do Facebook para se autenticar.

Com isso, temos algumas vantagens como, por exemplo:

  • Não precisamos mais criar nem salvar uma nova senha em cada aplicação de terceiros que formos utilizar
  • Posso revogar um acesso a qualquer momento sem deixar “dados” pra trás

O OAuth 2.0 estabelece quatro definições para nós, para que isso seja possível:

  • Resource Owner: o “dono do recurso”
  • Resource Server: servidor que possui os recursos protegidos
  • Authorization Server: servidor que gera um token que permite que o cliente acesse os recursos que o Resource Owner permitiu
  • Client: aplicação que acessa os recursos no Resource Server em nome do usuário

Abaixo, ilustrei as definições descritas acima para melhor entendimento

  1. O Resource Owner através de um Client tenta acessar o Resource Server (mantendo o exemplo anterior, vamos imaginar que seja o Medium);
  2. Esse Resource Server “confia” em um Authorization Server (seguindo o mesmo exemplo, esse cara seria o Facebook);
  3. O Resource Owner se autentica no Authorization Server;
  4. O Authorization Server retorna um token de autenticação válido para o Client;
  5. O Client acessa o Resource Server.
IdentityServer 4
Figura 1

Bom, agora que entendemos o fluxo básico do funcionamento do protocolo OAuth 2.0, vamos para o OpenID Connect.

OpenID Connect

O OpenID Connect é uma camada de identidade bem simples, criado sob o protocolo OAuth 2.0. Conforme dito acima, o OAuth 2.0 fornece um mecanismo de autenticação que gerará um token de acesso para acessarmos recursos protegidos em uma aplicação qualquer, porém, ele apenas “autentica”, não nos fornecendo nenhuma informação de identidade do usuário.

O OpenID Connect implementa uma “extensão” para o protocolo OAuth 2.0. É ele que vai nos fornecer informações sobre o usuário final na forma de um id_token que verifica a identidade do usuário e fornece informações básicas de perfil do mesmo.

Identity Server 4

O Identity Server 4 é um middleware feito na tecnologia .NET que utiliza o Oauth 2 e o OpenID Connect, e tem como finalidade permitir que diferentes aplicações (independentemente de tecnologia) “conversem entre si”. Ele também permite a criação de Single Sign-On, proteção de web API’s e gerenciamento de autorização de acesso.

No Identity Server 4 nós possuimos três definições, que seguem abaixo:

  • Users: é uma pessoa, de fato, que possua as credenciais necessárias para acessar o servidor de identidade;
  • Clients: aplicações autorizadas a acessar o meu servidor de identidade, pois assim como os Users, eles vão possuir um nome e/ou Id de acesso;
  • Scopes: são basicamente as informações que um Client deseja acessar no meu servidor de identidade

Bom, agora que já temos uma visão geral de como tudo funciona, na parte 2 desse artigo vamos começar a implementar o nosso servidor de identidade com o Identity Server 4 e com o Asp.Net Core 2.

Documentação: http://docs.identityserver.io