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:
- Cliente e servidor estão no .NET4 (parte do cliente no perfil do cliente)
- O servidor expõe usando o WCF REST
- 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:
- Antes de o cliente tentar se autenticar, ele gera um par de chaves Diffie-Hellman usando a
ECDiffieHellmanCng
classe - 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).
- O servidor autentica a combinação de nome de usuário / senha, se for bem-sucedida, faz o seguinte:
- Cria um token de sessão exclusivo
- Gera seu próprio par de chaves DH e calcula o segredo compartilhado da chave pública fornecida pelo cliente
- 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
- Retorna o token da sessão, sua chave DH pública e uma mensagem de sucesso de autenticação
- 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?
fonte
Respostas:
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.
fonte
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
fonte