Não sei se tenho algum tipo de ponto cego ou o quê, mas li as especificações do OAuth 2 várias vezes e examinei os arquivos da lista de discussão, e ainda não encontrei uma boa explicação sobre por que a concessão implícita foi desenvolvido um fluxo para obter tokens de acesso. Comparado com o código de autorização concedido, parece desistir da autenticação do cliente sem um motivo muito convincente. Como isso é "otimizado para clientes implementados em um navegador usando uma linguagem de script" (para citar a especificação)?
Ambos os fluxos começam da mesma forma (fonte: http://tools.ietf.org/html/draft-ietf-oauth-v2-22 ):
- O cliente inicia o fluxo direcionando o agente do usuário do proprietário do recurso para o terminal de autorização.
- O servidor de autorização autentica o proprietário do recurso (por meio do agente do usuário) e estabelece se o proprietário do recurso concede ou nega a solicitação de acesso do cliente.
- Supondo que o proprietário do recurso conceda acesso, o servidor de autorização redireciona o agente do usuário de volta ao cliente usando o URI de redirecionamento fornecido anteriormente (na solicitação ou durante o registro do cliente).
- O URI de redirecionamento inclui um código de autorização (fluxo de código de autorização)
- O URI de redirecionamento inclui o token de acesso no fragmento de URI (fluxo implícito)
Aqui é onde os fluxos se dividem. Nos dois casos, o URI de redirecionamento neste momento é para algum terminal hospedado pelo cliente:
- No fluxo do código de autorização, quando o agente do usuário atinge esse ponto de extremidade com o código de autorização no URI, o código nesse ponto de extremidade troca o código de autorização junto com suas credenciais do cliente por um token de acesso que pode ser usado conforme necessário. Por exemplo, poderia gravá-lo em uma página da web que um script da página pudesse acessar.
- O fluxo implícito ignora completamente esta etapa de autenticação do cliente e apenas carrega uma página da web com o script do cliente. Há um truque interessante aqui com o fragmento de URL que impede que o token de acesso seja transmitido muito, mas o resultado final é basicamente o mesmo: o site hospedado pelo cliente exibe uma página com algum script que pode capturar o token de acesso .
Daí a minha pergunta: o que foi ganho aqui ao pular a etapa de autenticação do cliente?
fonte
Respostas:
Aqui estão os meus pensamentos:
O objetivo do código de autenticação + token no fluxo de código de autorização é que o token e o segredo do cliente nunca sejam expostos ao proprietário do recurso porque eles viajam servidor a servidor.
Por outro lado, o fluxo de concessão implícito é para clientes implementados inteiramente usando javascript e executando no navegador do proprietário do recurso. Você não precisa de nenhum código do lado do servidor para usar esse fluxo. Então, se tudo acontecer no navegador do proprietário do recurso, não faz mais sentido emitir o código de autenticação e o segredo do cliente, porque o token e o segredo do cliente ainda serão compartilhados com o proprietário do recurso. A inclusão do código de autenticação e do segredo do cliente apenas torna o fluxo mais complexo sem adicionar mais segurança real.
Então a resposta sobre "o que foi ganho?" é "simplicidade".
fonte
Auth code
, juntamente comclient_id
eclient_secret
são usados para identificar clientes confiáveis que podem atualizar tokens para um logon prolongado e para "logon offline" . No entanto, em um aplicativo do lado do cliente, não há nenhuma maneira de registrar cada cliente, daí o "simplificado" concessão tipo implícito para acesso temporário às informações do usuárioEstá lá por razões de segurança, não por simplicidade.
Você deve considerar a diferença entre o agente do usuário e o cliente :
O user-agent é o software pelo qual o usuário ("proprietário do recurso") se comunica com outras partes do sistema (servidor de autenticação e servidor de recursos).
O cliente é o software que deseja acessar os recursos do usuário no servidor de recursos.
No caso de agente-usuário e cliente dissociados, a concessão do código de autorização faz sentido. Por exemplo, o usuário usa um navegador da web (agente do usuário) para fazer login com sua conta do Facebook no Kickstarter. Nesse caso, o cliente é um dos servidores do Kickstarter, que lida com os logins do usuário. Este servidor obtém o token de acesso e o token de atualização do Facebook. Portanto, esse tipo de cliente considerado "seguro", devido ao acesso restrito, os tokens podem ser salvos e o Kickstarter pode acessar os recursos dos usuários e até atualizar os tokens de acesso sem a interação do usuário.
Se o agente do usuário e o cliente estiverem acoplados (por exemplo, aplicativo móvel nativo, aplicativo javascript), o fluxo de trabalho de autorização implícita pode ser aplicado. Ele depende da presença do proprietário do recurso (para inserir as credenciais) e não suporta tokens de atualização. Se esse cliente armazenar o token de acesso para uso posterior, será um problema de segurança, pois o token poderá ser facilmente extraído por outros aplicativos ou usuários do cliente. A ausência do token de atualização é uma dica adicional, de que este método não foi projetado para acessar os recursos do usuário na ausência do usuário.
fonte
A explicação usual é que a concessão implícita é mais fácil de implementar quando você está usando um cliente JavaScript. Mas acho que essa é a maneira errada de encarar. Se você estiver usando um cliente JavaScript que solicita recursos protegidos diretamente via XMLHttpRequest, a concessão implícita é sua única opção, embora seja menos segura. *
A concessão do Código de Autorização fornece segurança adicional, mas só funciona quando você tem um servidor da Web solicitando os recursos protegidos. Como o servidor da Web pode armazenar o token de acesso, você corre menos risco de expor o token de acesso à Internet e pode emitir um token que dura muito tempo. E como o servidor da Web é confiável, ele pode receber um "token de atualização", para obter um novo token de acesso quando o antigo expirar.
Mas - e este é um ponto fácil de perder - a segurança do fluxo do código de autorização funciona apenas se o servidor da web estiver protegido com uma sessão, estabelecida com a autenticação do usuário (login). Sem uma sessão, um usuário não confiável poderia apenas fazer solicitações ao servidor da Web, usando o client_id, e seria o mesmo como se o usuário tivesse o token de acesso. Adicionar uma sessão significa que apenas um usuário autenticado pode acessar os recursos protegidos. O client_id é apenas a "identidade" do webapp JS, não a autenticação do referido webapp.
Isso também significa que você pode encerrar a sessão antes que o token OAuth expire. Não existe uma maneira padrão de invalidar um token de acesso. Mas se a sua sessão expirar, o token de acesso será inútil, pois ninguém o conhece, exceto o servidor da web. Se um usuário não confiável obtiver acesso à sua chave de sessão, ele poderá acessar os recursos protegidos apenas enquanto a sessão for válida.
Se não houver servidor da web, você precisará usar a concessão implícita. Mas isso significa que o token de acesso é exposto à Internet. Se um usuário não confiável obtiver acesso a ele, ele poderá usá-lo até que ele expire. Isso significa que eles terão acesso a ele por mais tempo do que com uma concessão do Código de autorização. Portanto, considere fazer com que o token expire mais cedo e evite dar acesso a recursos mais sensíveis.
* EDIT: Mais recentemente, as pessoas recomendam que você evite usar a concessão implícita, mesmo em aplicativos Web sem servidor. Em vez disso, você pode usar a concessão do Código de Autorização configurada com um segredo vazio, juntamente com o PKCE. A concessão do código de autenticação evita armazenar o token de acesso no histórico do navegador e o PKCE evita expô-lo se alguém seqüestrar o URL de redirecionamento para roubar o código de autenticação. Nesse caso, você precisaria do servidor para evitar o retorno de um token de atualização, pois seu cliente provavelmente não pode armazená-lo com segurança. E deve emitir um token de acesso com as mesmas limitações mencionadas acima.
fonte
Tudo se resume a: Se um usuário estiver executando um aplicativo Web baseado em navegador ou "público", (JavaScript) sem componente do servidor, o usuário confia implicitamente no aplicativo (e no navegador em que é executado, potencialmente com outro navegador) aplicativos baseados em ...).
Não há servidor remoto de terceiros, apenas o servidor de recursos. Não há benefício para um código de autorização, porque não há outro agente além do navegador agindo em nome do usuário. Não há benefício para as credenciais do cliente pelo mesmo motivo. ( Qualquer cliente pode tentar usar esse fluxo.)
As implicações de segurança, no entanto, são significativas. Em http://tools.ietf.org/html/rfc6749#section-10.3 :
Em http://tools.ietf.org/html/rfc6749#section-10.16 :
fonte
Não sei se entendi corretamente a resposta e o comentário de Dan. Parece-me que a resposta afirmou que alguns fatos estão corretos, mas indica exatamente o que o OP pediu. Se bem entendi, a principal vantagem do fluxo implícito de concessão é que um cliente como o aplicativo JS (por exemplo, extensão do Chrome) não precisa expor o segredo do cliente.
Dan Taflin disse:
Talvez eu tenha entendido mal você, mas o cliente (neste caso, o aplicativo JS) deve passar a credencial do cliente (chave e segredo do cliente) para o servidor de recursos no fluxo do código de autorização, certo? O segredo do cliente não pode ser "mantido de JS".
fonte
Embora o Implicit Grant tenha sido projetado para oferecer suporte a aplicativos que não poderiam proteger um segredo do cliente, incluindo aplicativos JavaScript do lado do cliente, alguns provedores estão implementando uma alternativa usando o Código de Autorização sem um Segredo do Cliente. O OAuth 2.0 IETF RFC-6749 foi publicado em 2012 e as recomendações atuais são de algumas discussões recentes a partir de 2017.
A discussão de 2017 na lista de discussão IETF OAuth está disponível nestes implementadores:
Leia mais aqui:
A mudança para o código de autenticação sem o segredo do cliente da concessão implícita também é mencionada para aplicativos móveis aqui:
fonte
além das outras respostas, também é importante perceber que o perfil implícito permite um fluxo apenas do canal frontal, em oposição ao fluxo do código de autorização que requer uma chamada de volta ao servidor de autorização; isso se torna evidente no OpenID Connect, que é um protocolo SSO construído sobre o Auth 2.0, em que o fluxo implícito se assemelha à ligação SAML POST bastante popular e o fluxo do código de autorização se assemelha à ligação SAML Artifact menos amplamente implantada
fonte
No fluxo implícito, se o navegador do usuário estiver corrompido (extensão / vírus incorreto), a corrupção obterá acesso aos recursos do usuário e poderá fazer as coisas ruins.
No fluxo de autenticação, a corrupção não pode porque não conhece o segredo do cliente.
fonte
https://tools.ietf.org/html/rfc6749#page-8
fonte
Acho que Will Cain respondeu isso quando disse: "Não há benefício para as credenciais do cliente pelo mesmo motivo. (Qualquer cliente pode tentar usar esse fluxo.)" Considere também que o redirect_uri para o fluxo implícito talvez seja "localhost" - sem retorno de chamada é feito do servidor de autorização para o fluxo implícito. Como não há como confiar previamente no cliente, o usuário precisaria aprovar a liberação das declarações do usuário.
fonte
A concessão implícita permite obter tokens do ponto de extremidade de autorização com a
GET
. Isso significa que o servidor de autorização não precisa suportar o CORS.Se isso não for uma preocupação e se não houver outros problemas relacionados ao servidor de autorização que não sejam flexíveis (por exemplo, os tokens de atualização não são opcionais, por algum motivo), o fluxo do código de autorização será o preferido, mesmo para clientes públicos, de acordo com as tendências recentes do setor e, pelo menos, para esta instância (atual) de um rascunho oficial .
Historicamente, havia outros motivos para implementar o fluxo implícito, mas parece que eles atualmente são superados pelas vantagens de segurança oferecidas pela concessão do código de autorização, incluindo:
fonte
Acabei de encontrar um artigo sobre o OAuth 2.0. O autor afirma que a razão por trás do fluxo implícito é que os aplicativos JS eram muito restritos nas solicitações:
https://medium.com/securing/what-is-going-on-with-oauth-2-0-and-why-you-should-not-use-it-for-authentication-5f47597b2611
fonte