Qual é o fluxo OAuth 2.0 correto para um aplicativo móvel

87

Estou tentando implementar a autorização delegada em uma API da Web para aplicativos móveis usando OAuth 2.0. De acordo com a especificação, o fluxo de concessão implícito não oferece suporte a tokens de atualização, o que significa que uma vez que um token de acesso é concedido por um período específico de tempo, o usuário deve conceder permissões para o aplicativo novamente quando o token expira ou é revogado.

Acho que esse é um bom cenário para algum código javascript em execução em um navegador, conforme mencionado na especificação. Estou tentando minimizar as vezes que o usuário deve conceder permissões ao aplicativo para obter um token, então parece que o fluxo do código de autorização é uma boa opção, pois oferece suporte a tokens de atualização.

No entanto, esse fluxo parece depender muito de um navegador da web para realizar os redirecionamentos. Estou me perguntando se esse fluxo ainda é uma boa opção para um aplicativo móvel se um navegador da web incorporado for usado. Ou devo ir com o fluxo implícito?

Pablo Cibraro
fonte
1
A pergunta seria - a prioridade mais alta é que o usuário nunca mais tenha que digitar uma senha novamente após o primeiro login?
mínimo privilegiado
Sim, esse é exatamente o meu requisito. O usuário deve digitar a senha apenas uma vez. No entanto, não quero configurar um token com vida útil infinita e mantê-lo no aplicativo móvel, pois isso iria contra a capacidade de revogar o token. (A menos que eu adicione alguma lógica no aplicativo móvel para detectar que a solicitação não foi autorizada, então eu solicito um novo token depois disso)
Pablo Cibraro
1
Você pode adicionar um token com vida útil infinita e ainda revogá-lo. E sim, a lógica do aplicativo deve ser capaz de detectar isso. A RFC 6750 define uma maneira de verificar se o erro é devido a um token revogado.
Pedro Felix
1
Por favor, evite visualizações na web (a menos que você possua a pilha completa e não esteja usando o login social), que abre a possibilidade de comprometer as senhas. Quando minhas credenciais são solicitadas por um agente de usuário integrado de terceiros, eu desinstala o aplicativo. Algumas APIs agora até proíbem integrações como esta dev.fitbit.com/docs/oauth2 Forneci outra resposta para esclarecer ainda mais alguns desses conceitos ( stackoverflow.com/a/38582630/752167 )
Matt C

Respostas:

90

Esclarecimento: Mobile App = Native App

Conforme declarado em outros comentários e em algumas fontes online, implícito parece ser um ajuste natural para aplicativos móveis, no entanto, a melhor solução nem sempre é clara (e, de fato, implícito não é recomendado pelos motivos discutidos abaixo).

Práticas recomendadas de app nativo OAuth2

Seja qual for a abordagem que você escolher (existem algumas desvantagens a serem consideradas), você deve prestar atenção às práticas recomendadas descritas aqui para aplicativos nativos usando OAuth2: https://tools.ietf.org/html/rfc8252

Considere as seguintes opções

Implícito

Devo usar implícito?

Para citar a Seção 8.2 https://tools.ietf.org/html/rfc8252#section-8.2

O fluxo de autorização de concessão implícita do OAuth 2.0 (definido na Seção 4.2 do OAuth 2.0 [RFC6749]) geralmente funciona com a prática de realizar a solicitação de autorização no navegador e receber a resposta de autorização por meio de comunicação entre aplicativos baseada em URI.
No entanto, como o fluxo implícito não pode ser protegido por PKCE [RFC7636] (que é exigido na Seção 8.1), o uso do fluxo implícito com aplicativos nativos NÃO É RECOMENDADO .

Os tokens de acesso concedidos por meio do fluxo implícito também não podem ser atualizados sem a interação do usuário, tornando o fluxo de concessão do código de autorização - que pode emitir tokens de atualização - a opção mais prática para autorizações de aplicativos nativos que exigem a atualização dos tokens de acesso.

Código de autorização

Se você optar pelo Código de autorização, uma abordagem seria usar o proxy por meio de seu próprio componente de servidor da web, o que enriquece as solicitações de token com o segredo do cliente para evitar armazená-lo no aplicativo distribuído nos dispositivos.

Trecho abaixo de: https://dev.fitbit.com/docs/oauth2/

O fluxo de Concessão do Código de Autorização é recomendado para aplicativos que possuem um serviço da web. Esse fluxo requer comunicação de servidor para servidor usando o segredo do cliente de um aplicativo.

Nota: Nunca coloque o segredo do seu cliente em código distribuído, como aplicativos baixados por meio de uma loja de aplicativos ou JavaScript do lado do cliente.

Os aplicativos que não têm um serviço da web devem usar o fluxo de concessão implícita.

Conclusão

A decisão final deve levar em consideração sua experiência de usuário desejada, mas também seu apetite por risco, após fazer uma avaliação de risco adequada das abordagens selecionadas e compreender melhor as implicações.

Uma ótima leitura está aqui https://auth0.com/blog/oauth-2-best-practices-for-native-apps/

Outro é https://www.oauth.com/oauth2-servers/oauth-native-apps/ que afirma

A melhor prática atual da indústria é usar o Fluxo de Autorização omitindo o segredo do cliente e usar um agente de usuário externo para concluir o fluxo. Um agente de usuário externo normalmente é o navegador nativo do dispositivo (com um domínio de segurança separado do aplicativo nativo) para que o aplicativo não possa acessar o armazenamento de cookies ou inspecionar ou modificar o conteúdo da página dentro do navegador.

Consideração PKCE

Você também deve considerar o PKCE, que é descrito aqui https://www.oauth.com/oauth2-servers/pkce/

Especificamente, se você também estiver implementando o Authorization Server, https://www.oauth.com/oauth2-servers/oauth-native-apps/checklist-server-support-native-apps/ declara que você deve

  • Permite que os clientes registrem esquemas de URL personalizados para seus URLs de redirecionamento.
  • Oferece suporte a URLs de redirecionamento de IP de loopback com números de porta arbitrários para oferecer suporte a aplicativos de desktop.
  • Não presuma que os aplicativos nativos podem manter um segredo. Exigir que todos os aplicativos declarem se são públicos ou confidenciais e apenas emitir segredos do cliente para aplicativos confidenciais.
  • Oferece suporte à extensão PKCE e exige que os clientes públicos a utilizem.
  • Tente detectar quando a interface de autorização é incorporada na visualização da web de um aplicativo nativo, em vez de iniciada em um navegador do sistema, e rejeite essas solicitações.

Consideração de visualizações da web

Existem muitos exemplos de uso de Web Views, ou seja, um agente de usuário incorporado, mas essa abordagem deve ser evitada (especialmente quando o aplicativo não é original) e, em alguns casos, pode resultar na proibição de usar uma API como trecho abaixo a partir daqui demonstra

Qualquer tentativa de incorporar a página de autenticação do OAuth 2.0 resultará no banimento do seu aplicativo da API Fitbit.

Por questões de segurança, a página de autorização do OAuth 2.0 deve ser apresentada em uma visualização de navegador dedicada. Os usuários do Fitbit só podem confirmar que estão se autenticando no site Fitbit.com genuíno se tiverem as ferramentas fornecidas pelo navegador, como a barra de URL e as informações do certificado Transport Layer Security (TLS).

Para aplicativos nativos, isso significa que a página de autorização deve ser aberta no navegador padrão. Os aplicativos nativos podem usar esquemas de URL personalizados como URIs de redirecionamento para redirecionar o usuário de volta do navegador para o aplicativo que está solicitando permissão.

Os aplicativos iOS podem usar a classe SFSafariViewController em vez de alternar para o Safari. O uso da classe WKWebView ou UIWebView é proibido.

Os aplicativos Android podem usar as guias personalizadas do Chrome em vez de alternar para o navegador padrão. O uso de WebView é proibido.

Para esclarecer ainda mais, aqui está uma citação desta seção de um rascunho anterior do link de melhores práticas fornecido acima

Os agentes de usuário incorporados, comumente implementados com visualizações da web, são um método alternativo para autorizar aplicativos nativos. No entanto, eles não são seguros para uso por terceiros, por definição. Eles envolvem o login do usuário com suas credenciais de login completas, apenas para ter seu escopo reduzido para credenciais OAuth menos potentes.

Mesmo quando usados ​​por aplicativos próprios confiáveis, os agentes de usuário incorporados violam o princípio do menor privilégio ao obter credenciais mais poderosas do que precisam, aumentando potencialmente a superfície de ataque.

Em implementações típicas baseadas em visualização da web de agentes de usuário incorporados, o aplicativo host pode: registrar todas as teclas digitadas no formulário para capturar nomes de usuários e senhas; enviar formulários automaticamente e ignorar o consentimento do usuário; copie os cookies de sessão e use-os para executar ações autenticadas como o usuário.

Incentivar os usuários a inserir credenciais em uma visualização da web incorporada sem a barra de endereço usual e outros recursos de identidade que os navegadores têm torna impossível para o usuário saber se está acessando o site legítimo e, mesmo quando está, isso os treina que não há problema em inserir credenciais sem validar o site primeiro.

Além das questões de segurança, as visualizações da web não compartilham o estado de autenticação com outros aplicativos ou o navegador do sistema, exigindo que o usuário faça login para cada solicitação de autorização e levando a uma experiência do usuário ruim.

Devido ao acima exposto, o uso de agentes de usuário incorporados NÃO É RECOMENDADO, exceto quando um aplicativo primário confiável atua como o agente de usuário externo para outros aplicativos ou fornece logon único para vários aplicativos próprios.

Os servidores de autorização DEVEM considerar tomar medidas para detectar e bloquear logins por meio de user-agents incorporados que não sejam seus, quando possível.

Alguns pontos interessantes também são levantados aqui: /security/179756/why-are-developers-using-embedded-user-agents-for-3rd-party-auth-what-are-the- uma

Matt C
fonte
3
O Google está removendo o suporte para visualizações da web em 20 de abril de 2017 developers.googleblog.com/2016/08/…
Matt C
Para sua informação, as referências do documento no início desta resposta se não forem mais rascunho OAuth 2.0 para aplicativos nativos - tools.ietf.org/html/rfc8252
Kostiantyn Sokolinskyi
Obrigado @KostiantynSokolinskyi, editado de acordo com o link para rfc que não é mais rascunho
Matt C
@MattC Qual é a melhor forma de implementar o registro de um novo usuário? Devemos fazer isso no aplicativo ou no IDP? É possível fazer o login automático no registro de postagem do usuário? stackoverflow.com/questions/60187173/…
Yashvit
Desculpe, estou confuso com alguns detalhes ... Você poderia dar uma olhada? Obrigado! link ---> stackoverflow.com/q/61313694/4619958
ch271828n
25

Infelizmente, não acho que haja uma resposta clara para essa pergunta. No entanto, aqui estão as opções que identifiquei:

  • Se estiver tudo bem em pedir ao usuário suas credenciais, use as Credenciais de senha do proprietário do recurso . No entanto, isso pode não ser possível por alguns motivos, nomeadamente

    • Políticas de usabilidade ou segurança proíbem a inserção da senha diretamente no app
    • O processo de autenticação é delegado em um provedor de identidade externo e deve ser realizado por meio de um fluxo baseado em redirecionamento HTTP (por exemplo, OpenID, SAMLP ou WS-Federation)
  • Se o uso de um fluxo baseado em navegador for necessário, use o Fluxo de código de autorização . Aqui, a definição de redirect_urié um grande desafio, para o qual existem as seguintes opções:

    • Use a técnica descrita em https://developers.google.com/accounts/docs/OAuth2InstalledApp , onde um especial redirect_uri(por exemplo urn:ietf:wg:oauth:2.0:oob) sinaliza o endpoint de autorização para mostrar o código de autorização em vez de redirecionar de volta para o aplicativo cliente. O usuário pode copiar manualmente este código ou o aplicativo pode tentar obtê-lo a partir do título do documento HTML.
    • Use um localhostservidor no dispositivo (o gerenciamento da porta pode não ser fácil).
    • Use um esquema de URI personalizado (por exemplo myapp://...) que, quando desreferenciado, aciona um "manipulador" registrado (os detalhes dependem da plataforma móvel).
    • Se disponível, use uma "visualização da web" especial, como o WebAuthenticationBroker no Windows 8, para controlar e acessar as respostas de redirecionamento HTTP.

Espero que isto ajude

Pedro

Pedro Felix
fonte
Obrigado Pedro pela contribuição !. Sim, parece que o fluxo do código de autorização com o esquema de URI personalizado ou o Web View parece ser a melhor opção aqui.
Pablo Cibraro
1
Tudo depende se você deseja que o cliente digite a senha em uma visualização da web ou no aplicativo cliente. Se possível, eu preferiria o aplicativo cliente - então imediatamente troque o segredo por um token de acesso / atualização.
menor privilégio
Obrigado Dominick !. Meu cliente está usando o ADFS para autenticar os usuários, então eles desejam inserir as credenciais na página de login. A visualização da web funcionará para eles
Pablo Cibraro
5
Estou curioso para saber por que você recomendaria o "fluxo de código de autorização"? Você não precisaria de client_secret e client_id para trocar o código por um access_token? Achei que o fluxo "implícito" foi projetado para esses cenários, porque não exige que segredos sejam armazenados no dispositivo.
Eugenio Pace
1
implícito não oferece suporte a tokens de atualização OOB. No cenário de Pablo - eu claramente recomendaria o fluxo de RO. Parece que a empresa implantou aplicativos no mesmo back-end da empresa.
privilegiado
9

TL; DR: Usar Concessão de Código de Autorização com PKCE

1. Tipo de concessão implícita

O tipo de concessão implícita é bastante popular com aplicativos móveis. Mas não foi feito para ser usado dessa forma. Existem preocupações de segurança em torno do redirecionamento. Justin Richer afirma :

O problema surge quando você percebe que, ao contrário de um URL de servidor remoto, não há uma maneira confiável de garantir que a ligação entre um determinado URI de redirecionamento e um aplicativo móvel específico seja respeitado. Qualquer aplicativo no dispositivo pode tentar se inserir no processo de redirecionamento e fazer com que ele forneça o URI de redirecionamento. E adivinhe: se você usou o fluxo implícito em seu aplicativo nativo, acabou de entregar ao invasor seu token de acesso. Não há recuperação a partir desse ponto - eles têm o token e podem usá-lo.

E junto com o fato de que não permite que você atualize o token de acesso, é melhor evitá-lo.

2. Tipo de concessão do código de autorização

A concessão do código de autorização requer um segredo do cliente. Mas você não deve armazenar informações confidenciais no código-fonte do seu aplicativo móvel. As pessoas podem extraí-los. Para não expor o segredo do cliente, você deve executar um servidor como intermediário enquanto o Facebook escreve :

Recomendamos que tokens de acesso de aplicativo só sejam usados ​​diretamente dos servidores de seu aplicativo para fornecer a melhor segurança. Para aplicativos nativos, sugerimos que o aplicativo se comunique com seu próprio servidor e o servidor, em seguida, faça as solicitações de API para o Facebook usando o token de acesso de aplicativo.

Não é uma solução ideal, mas há uma maneira nova e melhor de fazer OAuth em dispositivos móveis: Chave de prova para troca de código

3. Tipo de concessão de código de autorização com PKCE (chave de prova para troca de código)

Fora das limitações, foi criada uma nova técnica que permite usar o Código de Autorização sem um segredo de cliente. Você pode ler o RFC 7636 completo ou esta breve introdução .

PKCE (RFC 7636) é uma técnica para proteger clientes públicos que não usam um segredo de cliente.

É usado principalmente por aplicativos nativos e móveis, mas a técnica também pode ser aplicada a qualquer cliente público. Ele requer suporte adicional do servidor de autorização, portanto, só é compatível com alguns provedores.

de https://oauth.net/2/pkce/

Filtro Johannes
fonte
-3

Usar um webview em seu aplicativo móvel deve ser uma maneira acessível de implementar o protocolo OAuth2.0 na plataforma Android.

Quanto ao campo redirect_uri, acho http://localhostuma boa escolha e você não precisa portar um servidor HTTP dentro da sua aplicação, porque você pode sobrescrever a implementação da onPageStartedfunção na WebViewClientclasse e parar de carregar a página da web http://localhostdepois de verificar o urlparâmetro.

public void onPageStarted(final WebView webView, final String url,
        final Bitmap favicon) {}
Zephyr
fonte
3
Práticas recomendadas para aplicativos nativos usando OAuth2: tools.ietf.org/html/draft-wdenniss-oauth-native-apps
Matt C
1
Como Matt C disse, acima. As visualizações da web são uma má ideia para aplicativos móveis - elas são inseguras, permitem que o aplicativo obtenha acesso às credenciais (portanto, não mais seguras do que RO) e não permitem que os usuários verifiquem o domínio e os certificados TLS. Use o tipo de concessão de código de autenticação com um manipulador de URI personalizado e certifique-se de usar o código de prova para troca de chaves (PKCE) para impedir que aplicativos maliciosos em seu telefone interceptem o código de autenticação e obtenham acesso à sua API.
ChrisC
2
A versão atualizada do rascunho do documento de práticas recomendadas do OAuth 2.0 para aplicativos nativos está em tools.ietf.org/html/draft-ietf-oauth-native-apps
Jeff Olson
-4

A experiência do usuário mais suave para autenticação e mais fácil de implementar é incorporar uma visualização da web em seu aplicativo. Processe as respostas recebidas pelo webview do ponto de autenticação e detecte o erro (cancelamento do usuário) ou aprovação (e extraia o token dos parâmetros de consulta de url). E acho que você pode realmente fazer isso em todas as plataformas. Fiz este trabalho com sucesso para o seguinte: aplicativos ios, android, mac, windows store 8.1, windows phone 8.1. Fiz isso para os seguintes serviços: dropbox, google drive, onedrive, box, basecamp. Para as plataformas não Windows, eu estava usando o Xamarin, que supostamente não expõe todas as APIs específicas da plataforma, mas expôs o suficiente para tornar isso possível. Portanto, é uma solução bastante acessível, mesmo de uma perspectiva de plataforma cruzada, e você não

Radu Simionescu
fonte
Ao fornecer uma experiência de usuário conveniente, veremos a indústria se afastar dessa abordagem. Como as visualizações da web abrem a possibilidade de comprometer as senhas, quando um agente de usuário incorporado me pede as credenciais, eu desinstala o aplicativo. Algumas APIs agora até banem essas integrações, como esta dev.fitbit.com/docs/oauth2
Matt C
Práticas recomendadas para aplicativos nativos usando OAuth2: tools.ietf.org/html/draft-wdenniss-oauth-native-apps
Matt C
Não vejo como um serviço habilitado para oauth pode proibir essa abordagem. É indetectável e seguro ... Alguns serviços habilitados para oauth fornecem clientes específicos de plataforma para facilitar a autenticação, e esses clientes realmente fazem o que eu descrevi aqui (mostrar um webview incorporado e rastrear alterações de url). A prática recomendada que você vinculou recomenda a mesma coisa: use o navegador do sistema ou o webview incorporado. Que argumento você está atacando com minha resposta? não está claro.
Radu Simionescu
Nenhum ataque pretendido, apenas destacando o problema. O link diz que existem duas abordagens que você mencionou, mas apenas um agente de usuário externo pode ser considerado seguro, especificamente ele diz que as opções para aplicativos nativos são "por meio de um agente de usuário integrado ou externo. Este documento recomenda externo os agentes do usuário, como as guias do navegador no aplicativo, são a única opção segura e utilizável para OAuth. "
Matt C
Outra citação "Em implementações típicas baseadas em visualização da web de agentes de usuário incorporados, o aplicativo host pode: registrar cada tecla digitada no formulário para capturar nomes de usuário e senhas; enviar formulários automaticamente e ignorar o consentimento do usuário" ... "O uso de user-agents incorporados NÃO É RECOMENDADO, exceto quando um aplicativo próprio confiável atua como o user-agent externo para outros aplicativos ou fornece logon único para vários aplicativos próprios. Os servidores de autorização DEVEM considerar tomar medidas para detectar e bloquear logins por meio de agentes de usuário incorporados que não são seus, quando possível
Matt C