Azure Active Directoy B2C
Uma boa alternativa para o Identity Server 4 (IDS4)?
O Identity Server tem sido uma ferramenta incrível, adotei ela como solução default para arquiteturas com múltiplas API e aplicações diversas que consomem essas APIs. Os concorrentes como Auth0 e outros sempre existiram, mas nunca conseguiram entregar algo com o mesmo nível de customização, simplicidade e eficiência quanto o IDS.
No entanto com a mudanças nas políticas de licenças e comercialização do IDS4 uma alerta acendeu e fui buscar novas alternativas, encontrei o Azure Active Directory B2C o provedor de identidade SAAS no Azure que me surpreendeu.
Por que IDS4 é tão relevante e por que pode deixar de ser?
1.) Com a mudanças na política comercial e a perda de suporte o IDS4 vai ficar para traz!
2.) Muita gente usou essa ferramenta, pois além de uma boa solução, tinha boa documentação e fazia parte do dotnet Foundation
Código aberto maduro:
IdentityServer usa a licença permissiva Apache 2 que permite construir produtos comerciais sobre ela. Também faz parte da .NET Foundation, que fornece governança e respaldo legal.
3.) A RFC é muito dinâmica e precisa que suas mudanças sejam implementadas ou ajustadas em produtos como IDS4
The OAuth 2.0 Authorization Framework
Por que precismos de Servidores de Identidade?
- ) Os navegadores se comunicam com os aplicativos da web
- ) Os aplicativos da web se comunicam com as APIs da web
- ) Aplicativos baseados em navegador se comunicam com APIs da web
- ) Aplicativos nativos se comunicam com APIs da web
- ) Aplicativos baseados em servidor se comunicam com APIs da web
Esses processos de comunicação as vezes precisavam autorizar apenas a aplicação, e as vezes precisavam autorizar os usuários que utilizam as aplicações. Essas demandas por fluxos diferentes criaram uma abstração de serviço de token, que é a base dos protocolos de Autorização dos dias atuais.
Essa ideia permitia que um token pudesse ser transmitido entre as comunicações, isso junto com alguns mecanismos de checagem de assinatura do token permitiam que o processo de persistência dos usuários e o processo de autenticação dos usuários pudesse ser centralizado, e mesmo assim ainda obter informações da sessão do usuário em diferentes pontos da comunicação.
A restruturação desse cenário para oferecer suporte a um serviço de token de segurança leva à seguinte arquitetura e protocolos.
Protocolos
Começamos então a falar rapidamente sobre esses protocolos, venha comigo a trajetória é longa, são muitos os degraus e eu espero que vocês tenham distintas concepções sobre esses protocolos, para que possamos sair desse artigo tão confusos quanto os artigos sobre esse assunto costumam nos deixar. (adaptando Clovis de barro filho)
- OAuth /OAuth2 (Padrão Aberto para Autorização, ele fornece um acesso seguro Delegado aos recursos do proprietário por meio de um token de serviço, você está dando a autorização de uma aplicação terceira a usar os recursos da sua aplicação, por exemplo o Google ou o Facebook)
- OpenId Connect (OIDC) (É um protocolo de autenticação criado no OAuth 2,0, é uma camada sobre o OAuth2 que estende o processo de Autorização servido pelo Access Token e fornece um Id Token um token com informações do usuário com seu perfil básico.)
- WS-Fed (O WS-Federation define mecanismos para permitir que diferentes reinos de segurança (realms) intermediar informações sobre identidades, atributos de identidade e autenticação)
- SAML (Security Assertion Markup Language) é um padrão aberto que permite que provedores de identidade (idP) passem credenciais de autorização para provedores de serviços (SP)
Um SSO deve fazer mais do que centralizar o processo de Autenticação e Autorização, ele tem que ser um poliglota e falar todos esses protocolos permitindo de fato um único ponto de acesso.
obs.: Devemos agradecimentos aos desenvolvedores Scott Brady & Dominick Baier os “caras” têm um mérito gigantesco, pois pegar a RFC e criar uma implementação no nível de usabilidade e segurança do IDS4 foi uma tarefa hercúlea.
O Azure AD B2C
O Azure AD B2C (Azure Active Directory B2C) é uma solução de CIAM (gerenciamento de acesso de identidade do cliente) .
Resolve problemas comuns como:
- ) Dimensionamento
- ) Monitoramento
- ) Tratamento automático de ameaças (DDOS, Password Spray Attack, brute Force)
Tem recursos interessantes
- ) SSO (OpenID Connect, OAuth 2.0 e SAML)
- ) Marca personalizada
- ) Perfil progressiva
- ) Autenticação de Dois Fatores
Disponibiliza os Seguinte Fluxos OAuth2.0 (Grant Types)
- ) Implicit Flow
- ) Authorization Code
- ) Client Credencials (com restrições)
- ) Resource Owner Password
Mas temos limitações ou Complicadores
- )Client Credencials
- )Web API chains
- )Faulted apps
moires detalhes das limitações aqui Limitações.
Tem mais gente olhando para esse mercado?
Azure Active Directoy
A Microsoft já fornecia uma solução que podia proteger aplicações limitando o acesso apenas aos usuários do Azure Active Directoy, aliais quase todos os conceitos básicos do Azure AD são aplicáveis no Azure AD B2C.
Mas isso era muito ruim nos cenários precisamos de usuários externos, vindos das redes sociais Facebook, por exemplo, e para aqueles usuários que precisam se registrar diretamente na aplicação.
Então veio o Az AD B2C pode centralizar todos esses fluxos em uma mesma ferramenta.
A documentação do Azure B2C é muito ampla e detalhada, então para se aprofundar leia a documentação, vou tentar explicar o que é preciso para entender as bases e a partir disso evoluirmos com a documentação.
Vamos entender três conceitos principais;
- Aplicações
- Provedores de identidade
- Fluxos de Usuários
Vamos analisar o Desenho abaixo
Aplicações são nossos conhecidos Clientes, podemos cria-las diretamente no portal do azure, definir seu tipo, web ou SPA, e se vai retornar id_token, Access token, além da url de retorno Redirect uri. Essas aplicações nos dão um clientId, parâmetro que será usado em todos o fluxo acima. Não especificamos explicitamente os tipos de Fluxos Oauth2, também conhecidos como Grant Type, mas de acordo com as características da aplicação esses fluxos são permitidos ou não.
Provedor de Identidade é o SSO (Single Sign On), o Azure B2C é um provedor de identidade, o Azure Active Directory, o IDS4 Identity server4.
Fluxos de usuário são customizações, que podem ser feitas nas telas de login, e informações que são transferidas via Token, em campos necessários para o cadastro de novos usuários e nos processos de servidores de identidade externos por exemplo Google, Azure Active Directory, Facebook etc.
O B2C na minha opinião dá um passo importante na “amigabilidade” da gestão de um IDP, pois encapsula muitos conceitos simplificando as configurações. Vou tentar resumir a história assim, o Azure B2C é uma aplicação que roda na nuvem do Azure que fala os diversos protocolos de Autorização e Autenticação, basicamente seu objetivo é fornecer tokens de usuário ou de Acesso.
A aplicação expõe uma API que aceite algumas operações HTTP, a principal é uma url /authorize que vai receber via QueryString alguns paramentos, esses parâmetros vão definir o fluxo de Autorização, vão definir quem é a aplicação que esta fazendo a chamada e qual a url de retorno.
Existe mais urls por exemplo /token usado em um fluxo que concede a autorização por meio de um código (Authorization code flow), mas no fim o que queremos são tokens.
Qual a minha proposta.
A internet está repleta de exemplo e vídeos que usam exemplos da Microsoft para ensinar o Azure B2C, a própria documentação do Az B2C abaixo mostra isso com muitos detalhes, então se você for como eu, e quer sofrer um pouco com um caso real, que tal pegar uma aplicação que usa IDS4 e tentar colocar o B2C no lugar, os dois falam os mesmos protocolos portanto podemos substituível um pelo outro certo?
Se você se interessou eu tenho um SEED no git hub, ele tem a seguinte Estrutura;
Com esse “cara” rodando podemos implementar um fluxo de implit Flow ou Autorization Code entre a aplicação SPA e o Azure B2C, obtendo um token de acesso para acessar a API.
Podemos implementar fluxos Implícito para o HangFire e para o Swagger, além de proteger a API de chamadas não autorizadas. Cada uma dessas aplicações vai precisar ser identificada com o tal do clientId, e para isso precisamos representar esse modelo de comunicação das aplicações no Azure AD B2C.
Vamos começar a usar o Azure B2C e criar esses recursos no portal do Azure.
Nesse ponto fiquem atentos, essa é a primeira dica, pois ao criar um Azure B2C, um novo tenant será gerado, e você vai precisar trocar seu diretório padrão para poder configurar seu Azure B2C, isso fica ali na parte superior, perto do seu usuário.
Vamos precisar criar Quatro aplicações diferentes.
- API
- SPA
- SWAGGER
- HANGFIRE
Criar a Aplicação que representa a SPA
Criar a Aplicação que representa a API
Na Aplicação de de API Expor a API e Criar o Escopo
Na Aplicação de UI dar permissão para a API
Liberar o uso do Access Token para implicit Flow
Podemos fazer um pequeno teste
Nos fluxos de usuários podemos testar a configuração do modelo das Aplicações, analisar as urls e conferir o Layout das telinhas.
Para isso precisamos trocar a URL de retorno de http://localhost:4200 para https://jwt.ms/
Customizar esse Fluxo de usuário
Podemos customizar esse fluxo, o atual já está customizado com HTML / CSS / Javascript em um template do processo de Sign in. Esse arquivo é hospedado em um Storage Account do Azure com as devidas configurações de CORS.
a customização é feita dentro de um fluxo de usuário no item Page Layout
ao entrar nesse item podemos optar por usar um custom page Content
Novo Fluxo de Usuário
Percebam que a Claims Role foi marcada.
essa claims é uma Custom Claims e foi criada no menu user Attribtes fora do fluxo de usuários
perceba que o fluxo de sign up tem o campo role para cadastro.
podemos customizar esse campo também , na mesma tela onde podemos definir um template
testando o fluxo novamente.
Agora vamos para o código, Primeiro no Front SPA.UI
Seed.Spa.Ui\src\app\common\services\auth.service.ts
>>> Comentar url de Autorize Atual e colocar essa abaixo;
var url =
this._authorizationUrl + "?" +
"client_id=" + encodeURI(this._client_id) + "&" +
"redirect_uri=" + encodeURI(this._redirect_uri) + "&" +
"response_type=" + encodeURI(this._response_type) + "&" +
"scope=" + encodeURI(this._scope) + "&" +
"response_mode=fragment" + "&" +
"state=" + encodeURI(state) + "&" +
"nonce=xyz";
>>> Trocar a url de authorize de /connect/authorize para authorize
this._authorizationUrl = GlobalService.getEndPoints().AUTH + '/authorize';
>>> Troca o código de CallBack que processa o retorno do token pelo abaixo.
Seed.Spa.Ui\src\assets\appsettings.development.json
>>> configurar os EndPoints
"AUTHAPI": "https://seedazb2c.b2clogin.com/seedazb2c.onmicrosoft.com/B2C_1_seed_sso/oauth2/v2.0/",
"AUTH": "https://seedazb2c.b2clogin.com/seedazb2c.onmicrosoft.com/B2C_1_seed_sso/oauth2/v2.0/",
Seed.Spa.Ui\src\app\global.service.ts
>>> Configurar o CLIENT_ID, Copiar da Aplicação criada no Azure B2C
>>> Configurar o Escopo
this.SCOPE = "openid profile https://seedazb2c.onmicrosoft.com/showmethecode-api/All";
Seed.Spa.Ui\src\app\main\main.component.ts
>>> Adicionar essa forma de ler as claims
Agora no Back na API
Seed.Api\Startup.cs
>>> Comentar Config AuthorityEndPoint SSO, e adicionar
>>> Instalar o pacote
Install-Package Microsoft.Identity.Web
>>> Adicionar as configurações do B2C
"AzureAdB2C": {
"Instance": "https://seedazb2c.b2clogin.com",
"ClientId": "c8fe6564-c356-4247-83ce-d53f7d9175b0",
"Domain": "seedazb2c.onmicrosoft.com",
"SignedOutCallbackPath": "/signout/B2C_1_seed_sso",
"SignUpSignInPolicyId": "B2C_1_seed_sso"
},
Seed.Api\appsettings.json
SWAGGER
o código abaixo ilustra como fazer as configurações inicias do Swagger. Esse código deve ser feito no método ConfigureServices da classe startup.cs
E no método Configure da a classe Startup.cs devemos definir o clientd, identificador que é gerado ao criar a aplicação no Azure B2C.
Podemos testar isso nesse link Swagger, basta clicar em autorize, marcar o último escopo de leitura, fazer um cadastro e poderá testar as chamadas protegidas.
Esse cadastro vai servir para acessar o HangFire também, mas antes disso , vamos ver como ficou a aplicação criada no Azure AD B2C
HangFire
Vamos criar mais uma aplicação no B2C, esse caso é como se fosse uma aplicação web clássica que precisa de autenticação, o hanfire usa uma interface IDashboardAuthorizationFilter que pede a implementação desse método Authorize nele verificamos se o user identiy está autenticado.
Configurando uma chave de segurança para aplaicação.
Aí basta configurar o Startup no método ConfigureServices
adicionar a section com as informações da Aplicação criada no B2C no arquivo appsettings.json
"AzureAdB2C": {
"Instance": "https://seedazb2c.b2clogin.com",
"ClientId": "ba713b80-08eb-43d6-b8fb-a8b2b8b226b3",
"Domain": "seedazb2c.onmicrosoft.com",
"SignedOutCallbackPath": "/signout/B2C_1_seed_sso",
"SignUpSignInPolicyId": "B2C_1_seed_sso",
"EditProfilePolicyId": "B2C_1_seed_sso",
"ClientSecret": "~33a.u.iS_F74pHMVY4Y.r9OO36eA1yMqu"
},
e pronto é so testar ,
Essa mesma abordagem de implementação usada para autentica o hangfire poderia ser aplicada em uma aplicação WEB SSR convencional, por exemplo uma aplicação MVC que precisasse de autenticação.
Lembre-se que o startup já estava configurado para o IDS4, então já existia configurações que não abordei aqui, todo o artigo foi baseado no SEED, observe a classe startup.cs no projeto hangfire.
No próximo vou implementar nesse mesmo Seed o fluxo Autorization Code Flow, ele é mais seguro que a implementação do Implicit Flow que fizemos nesse artigo. Além disso falta uma POC para o processo de Client Credencial que precisa interagir com o Azure Active Directory, uma vez que o B2C não dá suporte para esse fluxo diretamente.
Referencias
- IDS4
- Azure Active Directory B2C Overview
- Azure Active Directory B2C
- Azure Active Directory B2C (AAD B2C) for beginners
- Client Credentials Grant Flow with Azure AD B2C · Hossam Barakat
- Bruno Brito OAuth2
- Minicurso de Azure API Management com 8 módulos online e completamente gratuito.
- What is an Azure B2C Custom Policy / User Flow?
- Minhas Cicatrizes com o Identity Server 4 (IDS4)
- SAML VS WS-FED
- https://docs.microsoft.com/pt-br/azure/api-management/howto-protect-backend-frontend-azure-ad-b2c