Edit: Depois de postar isso, eu percebi que é quase a mesma resposta dada por Ali.S (ligeiramente diferente, mas a abordagem geral é a mesma.) Começou como algo completamente diferente.
Este método pressupõe que todas as comunicações estão sendo mantidas em uma série de túneis seguros. Como você consegue isso não importa. Eu sugeriria TLS, mas sou apenas eu.
- Cliente => Servidor do Jogo O cliente se conecta ao servidor do jogo e inicia uma sessão de login.
- Servidor de jogos => Servidor de autenticação O servidor de jogos se conecta ao servidor de autenticação e solicita um token de ID de sessão ao servidor de autenticação. Essa conexão é mantida aberta para escutar o êxito / falha do logon.
- Servidor de Jogo => Cliente O token da ID da sessão é enviado de volta ao cliente.
- Cliente => Servidor de autenticação O cliente envia a ID da sessão ao servidor de autenticação, juntamente com o nome de usuário e a senha do usuário, além de algumas informações sobre o servidor (IP, chave pública TLS, etc. Veja notas de rodapé)
- Servidor de autenticação => Servidor de jogos O servidor de autenticação envia informações sobre o logon para o servidor de jogos (estado de sucesso, nome de usuário, estatísticas, etc.) usando a ID da sessão fornecida pelo cliente.
- Servidor de jogos => Cliente O servidor de jogos informa ao cliente que a autenticação foi bem-sucedida e os deixa entrar.
- Todas as conexões, exceto a conexão inicial do cliente com o servidor do jogo, agora estão desativadas.
Como alternativa, você pode dar aos servidores de jogos uma porta dedicada para ouvir logins. Se você escolher essa rota, o fluxo ficaria assim:
- Cliente => Servidor de autenticação O cliente envia o nome de usuário, a senha e o IP do servidor para o servidor de autenticação.
- Servidor de autenticação => Servidor de jogo + Cliente Se o login for bem-sucedido, o servidor de autenticação envia um token exclusivo para o servidor e o cliente de jogo. Envie o IP do cliente também para o servidor do jogo, para que o token não possa ser roubado.
- Cliente => Servidor do Jogo O cliente envia o token para o servidor do jogo, onde é verificado e excluído no servidor do jogo. O servidor do jogo deixa o cliente entrar.
Essa segunda abordagem tornaria a implementação geral um pouco mais fácil.
Notas de rodapé:
A razão pela qual especifico que algumas informações devem ser enviadas sobre o servidor do jogo para o servidor de autenticação é para fortalecer o processo contra spoofs. O servidor pode verificar as informações para garantir que está autorizando a conexão que o player espera.
Os IDs de sessão não precisariam ser criptograficamente seguros, embora isso tornasse as conexões falsas um pouco mais difíceis se fossem.
Se você optar por seguir a rota TLS, poderá configurar um servidor de assinatura que assine todos os certificados usados por sua infraestrutura e adicioná-lo como uma CA confiável no software cliente / servidor. Contanto que você não solte seu certificado de assinatura, você poderá fornecer uma autenticação decente.
Para minimizar os ataques de DoS, faça o tempo limite das conexões após 20 segundos ou menos. Se durar mais do que isso, algo está errado e você não precisa esperar 3 minutos aguardando o tempo limite da conexão por conta própria.