Atualizar:
Adicionei este link à minha outra resposta como usar a autenticação JWT para a API da Web do ASP.NET aqui para qualquer pessoa interessada em JWT.
Conseguimos aplicar a autenticação HMAC para proteger a API da Web e funcionou bem. A autenticação HMAC usa uma chave secreta para cada consumidor que, tanto o consumidor quanto o servidor, sabem hmac hash uma mensagem, o HMAC256 deve ser usado. Na maioria dos casos, a senha com hash do consumidor é usada como uma chave secreta.
A mensagem normalmente é criada a partir de dados na solicitação HTTP, ou mesmo dados personalizados que são adicionados ao cabeçalho HTTP, a mensagem pode incluir:
- Registro de data e hora: hora em que a solicitação é enviada (UTC ou GMT)
- Verbo HTTP: GET, POST, PUT, DELETE.
- publicar dados e string de consulta,
- URL
Sob o capô, a autenticação HMAC seria:
O consumidor envia uma solicitação HTTP ao servidor da Web, após criar a assinatura (saída do hmac hash), o modelo da solicitação HTTP:
User-Agent: {agent}
Host: {host}
Timestamp: {timestamp}
Authentication: {username}:{signature}
Exemplo para solicitação GET:
GET /webapi.hmac/api/values
User-Agent: Fiddler
Host: localhost
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
A mensagem para o hash para obter assinatura:
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
Exemplo para solicitação POST com string de consulta (a assinatura abaixo não está correta, apenas um exemplo)
POST /webapi.hmac/api/values?key2=value2
User-Agent: Fiddler
Host: localhost
Content-Type: application/x-www-form-urlencoded
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
key1=value1&key3=value3
A mensagem para o hash para obter assinatura
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
key1=value1&key2=value2&key3=value3
Observe que os dados do formulário e a string de consulta devem estar em ordem; portanto, o código no servidor obtém a string de consulta e os dados do formulário para criar a mensagem correta.
Quando a solicitação HTTP chega ao servidor, um filtro de ação de autenticação é implementado para analisar a solicitação para obter informações: verbo HTTP, carimbo de data e hora, uri, dados do formulário e seqüência de caracteres de consulta, com base neles para criar a assinatura (use o hmac hash) com o segredo chave (senha com hash) no servidor.
A chave secreta é obtida do banco de dados com o nome de usuário na solicitação.
Em seguida, o código do servidor compara a assinatura na solicitação com a assinatura criada; se igual, a autenticação é aprovada, caso contrário, falhou.
O código para criar assinatura:
private static string ComputeHash(string hashedPassword, string message)
{
var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper());
string hashString;
using (var hmac = new HMACSHA256(key))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
hashString = Convert.ToBase64String(hash);
}
return hashString;
}
Então, como evitar ataques de repetição?
Adicione restrição ao carimbo de data / hora, algo como:
servertime - X minutes|seconds <= timestamp <= servertime + X minutes|seconds
(servertime: hora da solicitação chegando ao servidor)
E, armazene em cache a assinatura da solicitação na memória (use o MemoryCache, mantenha o tempo limite). Se a próxima solicitação vier com a mesma assinatura da solicitação anterior, ela será rejeitada.
O código de demonstração é apresentado aqui:
https://github.com/cuongle/Hmac.WebApi