Projetando Autenticação para API REST

11

Estou trabalhando em uma API para um serviço REST que vou produzir e consumir. Passei os últimos dias tentando descobrir como lidar bem com a autenticação e acho que finalmente criei algo.

Estou apresentando isso com base nos seguintes fatos sobre a pilha de aplicativos:

  1. Cliente e servidor estão no .NET4 (parte do cliente no perfil do cliente)
  2. O servidor expõe usando o WCF REST
  3. Eu realmente não quero manter o nome de usuário e a senha na memória do aplicativo

Em 3, eu queria usar uma forma de autenticação de token, para que, depois que as credenciais sejam verificadas pelo servidor, o cliente receba um token novamente para uso em todo o resto do aplicativo (isso permitirá que eu faça outras coisas, como atingir o tempo limite dos usuários, podendo mover os usuários sem problemas entre as versões da Web e da área de trabalho, etc). Depois de descobrir como fazer com que as chamadas sejam reproduzidas e resistentes a violações, vim com o seguinte:

  1. Antes de o cliente tentar se autenticar, ele gera um par de chaves Diffie-Hellman usando a ECDiffieHellmanCngclasse
  2. Ele envia a parte pública do par de chaves pela conexão, juntamente com o nome do usuário e a senha (sobre HTTPS, é claro).
  3. O servidor autentica a combinação de nome de usuário / senha, se for bem-sucedida, faz o seguinte:
    1. Cria um token de sessão exclusivo
    2. Gera seu próprio par de chaves DH e calcula o segredo compartilhado da chave pública fornecida pelo cliente
    3. Anota o token da sessão, o segredo compartilhado, o usuário e o tempo da "última ação" (usada para uma janela de expiração contínua) em seu banco de dados
    4. Retorna o token da sessão, sua chave DH pública e uma mensagem de sucesso de autenticação
  4. O cliente pega a chave DH da resposta, calcula o segredo compartilhado e armazena o token e o segredo na memória.

A partir desse momento, a combinação de token / segredo da sessão funciona como a maioria das outras APIs REST, com a solicitação sendo impressa por dedo e com registro de data e hora e, em seguida, gera algum tipo de HMAC. Sempre que um cliente executa uma ação no servidor, ele verifica o par de token / segredo, permite a ação se é válida e não expirou e atualiza o último registro de ação na sessão.

Não vejo falhas óbvias e provavelmente estou com excesso de engenharia para isso, mas preciso aprender como fazer isso em algum momento. O HMAC evita ataques de repetição, a negociação do DH ajuda a impedir ataques do MITM (não consigo pensar em um ataque viável do alto da minha cabeça entre o HMAC / DH).

Algum buraco que alguém possa fazer?

Matt Sieker
fonte
Não vejo como a geração de chaves DH adiciona segurança em comparação com o simples uso de HTTPS em qualquer lugar e o uso de cookies de sessão antigos. Quando usado corretamente, o HTTPS já protege contra ataques do tipo intermediário e de repetição.
Lie Ryan

Respostas:

5

Em vez de inventar o seu próprio, considere ler a API do OpenAM e emprestá-la.

http://forgerock.com/openam.html

O OpenAM Wiki é particularmente útil

https://wikis.forgerock.org/confluence/display/openam/Home

Você não precisa usar seus componentes. Mas se você usar a API deles, descobrirá que sua vida será mais simples a longo prazo.

S.Lott
fonte
Hmm, não parece ruim, uma coisa que está me impedindo de usá-lo neste caso: somos uma loja .Net. Além disso, não há muito o que usar com o lado do servidor WCF. O link não spam que eu encontrei no google sobre ele aponta para o uso de WIF e WS-Federation.
226118 Matt Sieker
1
@ Matt Sieker: "Você não precisa usar seus componentes". Leia sobre a API deles em vez de inventar a sua.
21411 S.Lott
Ah, acho que entendo o que você quer dizer com os requisitos de retorno de chamada. Isso é interessante, posso investigar mais, se não neste projeto, para futuros. Em vez de fazer auth como um pedaço atômica, dividi-lo um pouco, para que o servidor pode controlar o que ele precisa partir do cliente ...
Matt Sieker
Inicialmente, lançamos nossa própria versão, mas depois nos mudamos para o OpenAM há vários anos no IG Group. Muito feliz com o produto de código aberto.
Robert Morschel
2

Eu concordo 100% com @ S.Lott que você não quer fazer o seu próprio. Sugiro procurar outra alternativa: o ACS (Serviço de Controle de Acesso) do Windows Azure. O ACS custa dinheiro, mas é muito barato (10.000 transações por US $ 0,01) e uma boa parte da infraestrutura é tratada. O WIF é alavancado no cliente.

Essa também é uma solução baseada em padrões / declarações - que é toda a moda. Confira este artigo sobre o uso do WCF, REST e ACS juntos .

Se você está pensando no futuro, esse também é um mecanismo que pode crescer com você - pois você possui aplicativos móveis fora do firewall, parceiros e assim por diante. Mesmo se você não quiser usá-lo, uma vez que adiciona uma dependência fora do seu firewall, você pode procurar idéias. Muito liso.

Boa sorte! -Conta

codingoutloud
fonte