Padrões de identificação modernos: OAuth 2.0, OpenID Connect, WebAuthn

Deixar ou não deixar? Essa é a questão…

Agora, em muitos sites, vemos a oportunidade de registrar-se ou fazer login usando redes sociais, e alguns sites oferecem o uso de chaves de segurança externas ou impressões digitais. O que é isso? Padrões de segurança bem projetados ou implementações proprietárias? Podemos confiar nessas tecnologias e usá-las no desenvolvimento de sites e na vida cotidiana? Vamos acertar. Portanto, agora existem vários padrões e tecnologias para identificar usuários do OAuth 2.0, OpenID Connect, WebAuthn, SAML 2.0, API de gerenciamento de credenciais, etc. Neste artigo, falarei sobre os três protocolos mais promissores OAuth 2.0, OpenID Connect e WebAuthn. E para entender como colocá-los em prática, faremos três trabalhos de laboratório. Usaremos o GitHub e o Google como plataformas para identificar usuários.em que a maioria tem contas.

imagem

OAuth 2.0


Vamos começar com o mais famoso protocolo OAuth 2.0. Foi publicado em 2012 como RFC 6749: O OAuth 2.0 Authorization Framework .

Usando o OAuth 2.0, um usuário permite que um site específico receba seus dados privados das redes sociais, mas sem transferir seus logins / senhas para o site. Por exemplo, quando você se registra em um site pelo Facebook, você apenas concede permissão a este site para obter seu nome, endereço de e-mail e outros dados particulares do Facebook.

Vamos lidar com a implementação técnica. Para simplificar, chamarei qualquer site que armazene credenciais de usuário na Rede Social. E o MySite nomeará qualquer site ou aplicativo que deseje obter dados do usuário da Rede Social.

imagem

O padrão define as seguintes funções:

  • Resource Owner — , MySite .
  • Client ( MySite) — , Authorization Server Resource Server .
  • Authorization Server — / , .
  • Resource Server — , API. Authorization Server Resource Server .

Authorization flow


  • MySite :
  • MySite Name ( ), Homepage ( MySite) Callback (, )
  • A rede social fornece o Client ID (às vezes chamado AppID) e o Client Secret.
  • O ID do desenvolvedor deve ser registrado no ID do cliente e no Segredo do cliente.

Agora o processo em si. Os detalhes de implementações específicas podem variar, mas a lógica geral sempre será a seguinte:

imagem

  1. O Proprietário do Recurso efetua logon no Cliente (MySite), seleciona a opção “logon usando a Rede Social”; o site redireciona o usuário para a Rede Social no Servidor de Autorização.
  2. O servidor de autorização verifica se o usuário tem uma sessão ativa e, se não, exibe o formulário de login.
  3. O Proprietário do Recurso digita seu nome de usuário / senha e confirma que certos dados particulares podem ser usados ​​pelo MySite, como nome de usuário ou endereço de email.
  4. O Authorization Server verifica o usuário e redireciona para o endereço de retorno de chamada com o resultado da autenticação e o "Código de autorização"
  5. Client “Authorization Code”, Client ID Client Secret.
  6. Authorization Server “access token” JWT (JSON Web Token), . JWT “refresh token”, c .
  7. Client API, “access token”.
  8. Resource Server “access token” (, Authorization Server) .

OAuth 2.0 (GitHub)


Há muitas instruções sobre como implementar a autorização do OAuth 2.0 usando redes sociais. Pessoalmente, gostei do artigo a seguir: Autenticação usando o GitHub OAuth 2.0 com NodeJS Ele detalha as etapas e fornece um programa de teste. Mas, para realmente entender o algoritmo, é melhor seguir todas as etapas com as mãos (solicitações http do navegador ou chamadas para curl). Vai.

Para começar, registre seu aplicativo no GitHub: github.com/settings/applications/new

Defina os parâmetros:


Para autorização para trabalhar em seu próprio site, os endereços devem ser reais, mas isso não é necessário para o trabalho de laboratório.

Obtenha do GitHub:

  • ID do cliente: ab8ec08a620c2
  • Segredo do cliente: e6fdd52b0a99e8fbe76b05c1b7bb93c1e

Obviamente, em todo trabalho de laboratório, todos os valores são falsos.

É assim que a obtenção do ID e segredo do cliente no site do GitHub se parece:

imagem

Agora, iniciamos a autorização. Acreditamos que a Etapa 1 já foi concluída: o usuário efetuou login no MySite e selecionou “Efetuar login usando o GitHub”. A etapa 2 do fluxo de chamadas é uma chamada no formato REST:

https://github.com/login/oauth/authorize?client_id=ab8ec08a620c2


  • o endereço é o ponto de login no github
  • client_id é o ID do cliente emitido durante o registro

Como resultado dessa chamada, o GitHub mostra uma janela para autorização:

imagem

Etapa 3: Digite o login / senha para acessar o GitHub

Etapa 4: O GitHub redireciona a solicitação para a Página inicial, nesta solicitação, vemos o código:

http://MySite/home?code=a29b348f63d21

Não há site de trabalho neste endereço, mas o principal é saber o código enviado para formar a próxima etapa 5:

https://github.com/login/oauth/access_token?client_id=ab8ec08a620c2&
client_secret=e6fdd52b0a99e8fbe76b05c1b7bb93c1e&
code=a29b348f63d21

  • o endereço é o ponto de recebimento do token de acesso no GitHub
  • client_id é o ID do cliente emitido durante o registro
  • client_secret é um segredo do cliente emitido durante o registro
  • código é o código que acabou de ser enviado

Etapa 6: em resposta recebida o token de acesso:

access_token=31b71cbd372acdbb20ec1644b824f3dd0&scope=&token_type=bearer

Etapa 7: insira o access_token no cabeçalho da solicitação e chame a API do GitHub:

curl -H "Authorization: token 31b71cbd372acdbb20ec1644b824f3dd0" https://api.github.com/user

Etapa 8: em resposta, obtemos JSON com informações úteis sobre mim que você pode usar para criar um perfil no MySite:

{
  "login": "AlexeySushkov",
  "html_url": "https://github.com/AlexeySushkov",
  "repos_url": "https://api.github.com/users/AlexeySushkov/repos",
  "name": "Alexey Sushkov",
  "blog": "http://sushkov.ru",
  "location": "St.Petersburg, Russia",
  "email": "alexey.p.sushkov@gmail.com",
 ..
}  

De fato, examinamos apenas um cenário do OAuth 2.0. Existem vários cenários, cada um dos quais é usado dependendo do aplicativo, considerações de segurança, método de implantação etc. Uma descrição de todos os cenários pode ser encontrada, por exemplo, aqui: OAuth 2.0 em poucas palavras .

Conexão aberta


Com o OAuth 2.0 um pouco entendido. Agora vamos descobrir por que precisamos do OpenID Connect, que é um complemento para o OAuth 2.0:

  • C OAuth 2.0 .. access token, . access token MySite. OpenID Connect — (identity). .
  • OpenID Connect “service discovery”. SSO (Single Sign-On), .

Vamos olhar para o padrão do lado técnico.

O OpenID Connect (OIDC) é um padrão aberto do OpenID desenvolvido pelo consórcio OpenID Foundation . O OIDC estende o OAuth 2.0 com os seguintes recursos principais:

  • O Authorization Server, além de acessar o token e atualizar o token, retorna um "token de identidade" (ID Token). Está contido no mesmo JWT. As seguintes informações podem ser extraídas do Token de ID: nome de usuário, hora do login, data de validade do Token de ID. Os IDs de token podem ser transferidos entre os participantes.
  • OIDC fornece uma API adicional que permite solicitar informações sobre o usuário e suas sessões atuais.

O diagrama de interação no OpenID Connect tem a mesma aparência do OAuth. A única diferença no conteúdo das solicitações:

  • Na solicitação inicial de código, um atributo adicional, scope = openid, é adicionado.
  • Como resultado do algoritmo, o Cliente, além de acessar e atualizar o token, recebe um ID de Token.

OpenID Connect: Laboratório (Google)


Agora vamos ver o que o Google nos agradará nesse tópico. Existem instruções detalhadas para configurar e usar o OpenID Connect do Google e uma sandbox para usar a API do Google: Google OAuth 2.0 Playground .

Aqui, como no caso do OAuth 2.0, percorreremos as etapas e examinaremos os dados recebidos. Da mesma forma, acreditamos que o aplicativo está registrado, o ID do cliente e o Segredo do cliente são recebidos. A Etapa 1 é aprovada. A etapa 2 do fluxo de chamadas é uma chamada no formato REST:

https://accounts.google.com/o/oauth2/v2/auth?
response_type=code&
client_id=140797064495-b8b79j42m97nkkrlndfstikv8.apps.googleusercontent.com&
scope=openid%20email&
redirect_uri=http%3A//c18529.shared.hc.ru/wp-login.php&
state=765439764

O Google é um pouco mais complicado, porque eles prestam mais atenção à segurança:

  • endereço é o ponto de login no Google
  • response_type = code - espera receber código em resposta
  • client_id - ID do cliente emitido durante o registro
  • scope = email aberto - quais dados queremos acessar
  • redirect_uri - redirect_uri especificado durante o registro do aplicativo
  • state - o número gerado pelo cliente, que é transmitido entre o cliente e o AS para proteger contra interferência do invasor.

Etapa 3: não há formulário de entrada de senha, pois Eu já estava logado no Google.

Etapa 4: o Google redireciona a solicitação para a página inicial. Nesta solicitação, vemos o código:

http://MySite?state=123&code=4/xAFkcMzhyJhUErRJYwIyntSYN-WeJjfZHLiwWL4IaT-WkHzMU18xABlPmev-M_87wVbqTkQ1y93w6GB5&scope=email+openid+https://www.googleapis.com/auth/userinfo.email&authuser=0&prompt=none

Como no caso do GitHub, não existe um site em funcionamento neste endereço, mas isso não é necessário, o principal para nós é conhecer o código para formar a próxima Etapa 5. Isso também é um pouco mais complicado, porque O Google exige uma solicitação POST, não uma GET:

curl -d "code=4/xAFkcMzhyJhUErRJYwIyntSYN-WeJjfZHLiwWL4IaT-WkHzMU18xABlPmev-M_87wVbqTkQ1y93w6GB5&client_id=140797064495-b8b79j42m97nkkrlndfstikv8.apps.googleusercontent.com&
client_secret=HMVctrTicW6RC1Q8T&
redirect_uri=http%3A//c18529.shared.hc.ru/wp-login.php&
grant_type=authorization_code" 
-H "Content-Type: application/x-www-form-urlencoded" -X POST https://oauth2.googleapis.com/token

  • endereço é o ponto de recebimento de token no Google
  • código é o código que acabou de ser enviado
  • client_id é o ID do cliente emitido durante o registro
  • client_secret é um segredo do cliente emitido durante o registro
  • grant_type = permission_code - o único valor válido do padrão

Etapa 6: em resposta, access_token e id_token recebidos:

{
  "access_token": "ya29.Il_AB0KeKnjBJx0dhjm2nCLt1B-Mq0aQBW5T302JnlZfsxW1AXqLFfDJZRMi2R2WKG4OX4msKLjx4E4CSl4G_4ajAy3aqrf4pM0ic0jJr092pA67H9aktJktCbx",
  "expires_in": 3327,
  "scope": "openid https://www.googleapis.com/auth/userinfo.email",
  "token_type": "Bearer",
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3ZDU1ZmY0ZTEwOTkxZDZiMGVmZDM5MmI5MWEzM2U1
………………………………_…………………………………………………….._4mUTiMNSAHljap1hLD2hAzgOZWuQ"
}

O que fazer agora com essa riqueza?

Etapa 7: Com access_token, tudo fica claro: nós o incluímos em uma chamada de API, por exemplo, GMail:

curl -H "Authorization: Bearer ya29.a0Adw1xeWvFoxHKNICHnV6vFFj5TZdPQVlYD98h8wjW95ZEbHVui_pk7HGRoq3Q7MlVLV23xkVM0yyjSP8ClSlvfUy3b_IqvKQW5Lvwj38QzJhee-aH1grerB4pRpMzn_FGueigG_RGI56pKPgFBTr49cpynQy" https://www.googleapis.com/gmail/v1/users/alexey.p.sushkov@gmail.com/profile

Etapa 8: em resposta, obtemos o JSON com informações úteis:

{
 "emailAddress": "alexey.p.sushkov@gmail.com",
 "messagesTotal": 372543,
...
}

Agora vamos verificar a declaração de que id_token contém informações para autenticar o usuário e manter a sessão. Para fazer isso, você precisa descriptografar o conteúdo. A maneira mais fácil de fazer isso é entrar em contato com a API do Google em
oauth2.googleapis.com/tokeninfo e especificar o id_token recebido como parâmetro:

https://oauth2.googleapis.com/tokeninfo?id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3ZDU1ZmY0ZTEwOTkxZDZiMGVmZDM5MmI5MWEzM2U1NGMwZTIxOGIiLCJ0eXAiOi
………………………_……………………………...
SVQ5GQni3irfOzOXYEiqijp6TjGa_a-3jKcEsU5TbasZmAIejsdVcNy2_4mUTiMNSAHljap1hLD2hAzgOZWuQ

JSON obtido:
{
  "iss": "https://accounts.google.com",
  "email": "alexey.p.sushkov@gmail.com",
  "email_verified": "true",
  "iat": "1583257010",
  "exp": "1583260610",
  "typ": "JWT"
...
}

Vimos que id_token contém informações sobre o logon do usuário, a hora do recebimento e a vida útil do token. Podemos concluir que o OpenID Connect do Google está funcionando e pode ser usado para cenários relevantes.

Webauthn


API de autenticação da Web (também conhecida como WebAuthn):

  • O padrão permite que os usuários se identifiquem em sites e aplicativos usando chaves de segurança externas (por exemplo, chaves USB) ou por impressão digital e, posteriormente, por outros dados biométricos: face, retina.
  • — / «Public key cryptography». Public key cryptography — , . Private key ( ) , public key ( ) .
  • W3C (World Wide Web Consortium) FIDO, Google, Mozilla, Microsoft, Yubico. W3C HTTP, HTML, XML . WebAuthn. WebAuthn : Chrome, Firefox, Edge, Safari.


Comparadas ao OAuth 2.0, as seguintes funções são adicionadas ao WebAuthn:

Autenticador : uma chave de segurança externa (mídia física ou scanner de impressão digital) que autentica o usuário usando várias tecnologias, como BlueTooth / NFC / USB. Serve para:

  • Geração de credenciais de chave pública (pares de chave pública / privada).
  • O Authenticator armazena com segurança a chave privada em sua memória
  • Passa a chave pública para sistemas externos
  • Assina dados com uma chave privada e transfere o resultado para sistemas externos

O Authenticator usa o protocolo CTAP (Client to Authenticator Protocols) para interagir com o navegador.

Terceiro de Confiança : desempenha a mesma função que o "Servidor de Autorização" no OAuth 2.0, ou seja, verifica a identidade do usuário. Somente no OAuth 2.0 era o nome de usuário / senha e, no WenAuthn, as credenciais de chave pública.

Agente do usuário : integra o navegador e o aplicativo de rede, atende aos mesmos propósitos do Cliente no OAuth 2.0, ou seja, por um lado, interage com o usuário e fornece uma GUI e, por outro lado, interage com sistemas que armazenam credenciais de usuário .

Fluxo de autorização


Antes de iniciar o processo de autenticação, assim como no OAuth 2.0, você precisa executar as etapas preparatórias, apenas no OAuth 2.0 registramos o aplicativo e no WebAuth 2.0 registramos o usuário. A API de autenticação da Web especifica duas chamadas:

  • navigator.credentials.create - para criar credenciais de usuário
  • navigator.credentials.get - verifica as credenciais do usuário

Portanto, para se registrar, você deve chamar navigator.credentials.create.

Como resultado, o autenticador do usuário armazenará a chave privada de um site específico e a chave pública será armazenada na terceira parte confiável.

imagem

Depois disso, o processo de autenticação será o seguinte:

imagem

  1. “WebAuthn”. , , WebAuthn, “ ” “ ”. Relying Party Challenge. Challenge — , Code OAuth 2.0.
  2. Relying Party Challenge. , REST API.
  3. Authenticator- CTAP (Client to Authenticator Protocols). navigator.credentials.get c :

    • Challenge
  4. Authenticator , , .
  5. , Authenticator .
  6. O aplicativo envia os dados assinados para a terceira parte confiável.
  7. A terceira parte confiável descriptografa os dados usando a chave pública, verifica o desafio e autoriza o usuário.

Para consertar o material, realizamos trabalhos de laboratório:

WebAuthn: Laboratório (Google)


Para implementar o WebAuthn, apenas solicitações HTTP não podem ser dispensadas, pois você precisa chamar a API do navegador para interagir com o autenticador. Mas aqui o Google está feliz, criou uma caixa de areia com instruções passo a passo: seu primeiro WebAuthn .

Como resultado do trabalho, obtemos um aplicativo cliente-servidor JS que implementa a autenticação de impressão digital. Um deme de trabalho está localizado em .

Se você executá-lo em um smartphone com sensor de impressão digital, poderá ver o resultado do trabalho. Como de costume, primeiro prepare - registre o usuário:

imagem

Crie um nome de usuário / senha e anexe a impressão digital:

imagem

Depois disso, o programa mostra qual chave pública está anexada a essa impressão digital:

imagem

Agora você pode iniciar o script de autenticação. Como sempre, acreditamos que a Etapa 1 foi concluída e estamos no site. Para ir para a Etapa 2, clique em "Try Reauth". O navegador executará a Etapa 3 e entrará em interação com o Autenticador, que na Etapa 4 solicitará que você coloque o dedo

imagem

:

imagem

Conclusão


Portanto, examinamos os três protocolos mais comuns e promissores para identificação do usuário: OAuth 2.0, OpenID Connect, WebAuthn. Entendemos o escopo de sua aplicabilidade:

  • OAuth 2.0 - usado para registrar e fazer login de usuários em sites usando redes sociais. E também para obter dados do usuário nas redes sociais.
  • OpenID Connect — . OpenID Connect SSO .
  • WebAuthn — .


  • , , .
  • , , .
  • Faz sentido autenticar usuários em plataformas na nuvem como o Facebook ou Google, como eles empregam os melhores especialistas em segurança que podem fornecer todas as nuances da segurança.
  • Sugiro otimista sobre o futuro, porque Protocolo WebAuthn - uma chance real de se livrar da senha do dia a dia!

É só o começo!

Apêndice: outros protocolos de autenticação


Para completar, listarei os outros protocolos e tecnologias relevantes usados ​​para identificar os usuários:

SAML 2.0 (Linguagem de marcação de asserção de segurança)


O protocolo maduro de 2005, mas tem um conjunto limitado de cenários para a construção de sistemas SSO. Usa um formato de dados baseado em XML. Mais detalhes podem ser encontrados no artigo: “Quem usa o protocolo de autenticação SAML 2.0”

API de gerenciamento de credenciais


O desenvolvimento é realizado pela mesma organização que o WebAuthn - W3C. O padrão de gerenciamento de credenciais permite:

  • Armazene a identidade dos assinantes, o que permite aos usuários acessar sites sem inserir senhas, mas use senhas da loja.
  • Selecione as contas necessárias para entrar em determinados sites.
  • Permite usar logins / senhas inseridas em um dispositivo em outros dispositivos.

Um exemplo comum de implementação da API de gerenciamento de credenciais é o gerenciador de senhas do Google: passwords.google.com

Iniciativa para autenticação aberta (OATH)


Recursos de juramento

Uma lista completa de protocolos baseados em OAuth 2.0



All Articles