
Recentemente, eu precisava implementar o suporte à autenticação de usuário anônimo com base no OpenId Connect e OAuth 2.0 na plataforma ASP.NET Core. A especificação desses protocolos não será explicada aqui, pois existem artigos completos sobre o Habr. Vamos direto ao ponto.
Por que precisamos de um token anônimo? Para autorizar um usuário anônimo em um recurso de API, especialmente na arquitetura de microsserviços, ele também pode alterar o estado de nosso aplicativo, por exemplo, Vasya gostava de uma camiseta com gatos, adicionava-a à cesta da loja online e, possivelmente, fazia um pedido como hóspede. Para entender que era Vasily, o token anônimo contém o identificador do usuário anônimo e o identificador da sessão. Quando o Vasily efetua login, esses parâmetros serão incluídos no token autenticado.
Além disso, um token de acesso anônimo pode conter quaisquer declarações (ou reivindicações) adicionais.
As ferramentas
Implementação
O IdentityServer4 tem muitos exemplos no GitHub.
Adicionar suporte para tokens anônimos é bastante simples:
Cenário de interação
Considere obter um token anônimo para fluxo implícito e fluxo de código de autorização .
Solicitação de ponto de autorização
Para seguir a especificação, uma solicitação de um ponto de autorização para o fluxo implícito é a seguinte.
GET /connect/authorize? client_id=client1& scope=openid email api1& response_type=id_token token& redirect_uri=https://myapp/callback& state=abc& nonce=xyz& acr_values=0& response_mode=json
Para o fluxo de código de autorização, uma solicitação semelhante com response_type = code (PKCE é opcional).
As diferenças entre uma solicitação regular e anônima em dois parâmetros:
- O parâmetro acr_values = 0 indica o logon anônimo. Se estiver interessado, você pode ler a especificação do OpenId Connect .
- O parâmetro response_mode = json é usado para responder na forma de Json sem redirecionamentos desnecessários.
Recebendo token
Dependendo do status da autenticação, um token anônimo ou autenticado é retornado.
Fluxo implícito
Nesse caso, o ponto de autorização responde na forma de Json, incluindo o token de acesso.
{ "id_token": <id_token>, "access_token": <access_token>, "token_type": "Bearer", "expires_in": "2592000", "scope": "openid email api1", "state": "abc", "session_state": <optional> }
Fluxo do código de autorização
Com essa abordagem, o ponto de autorização responde na forma de Json, incluindo o código de autorização.
{ "code": <authorization_code>, "scope": "openid email api1", "state": "abc", "session_state": <optional> }
Em seguida, você precisa trocar o código pelo token usando o método padrão.
Nós formamos uma solicitação para o ponto final do token.
POST /connect/token client_id=client2& client_secret=secret& grant_type=authorization_code& code=`& redirect_uri=https://myapp/callback
Como resultado, o terminal do token responde na forma de Json, incluindo o token de acesso.
{ "id_token": <id_token>, "access_token": <access_token>, "token_type": "Bearer", "expires_in": "2592000", "scope": "openid email api1" }
Comparando tokens anônimos e autenticados
Se o servidor de autorização não contiver dados de autenticação, obteremos um token anônimo.
{ "nbf": 1566849147, "exp": 1569441147, "iss": "https://server", "aud": [ "https://server/resources", "api" ], "client_id": "client1", "sub": "abda9006-5991-4c90-a88c-c96764027347", "auth_time": 1566849147, "idp": "local", "ssid": "9e6453dbaf5ffdb03f08812f759d3cdf", "scope": [ "openid", "email", "api1" ], "amr": [ "anon" ] }
Você pode determinar que o usuário é anônimo usando o método de autenticação (amr).
O identificador da sessão "geral" (ssid) e o identificador do assunto (sub) serão incluídos no token autenticado, no logon do usuário subsequente.
Caso o usuário esteja logado, obtemos um token autenticado.
{ "nbf": 1566850295, "exp": 1566853895, "iss": "https://server", "aud": [ "https://server/resources", "api" ], "client_id": "client1", "sub": "bob", "auth_time": 1566850295, "idp": "local", "aid": "abda9006-5991-4c90-a88c-c96764027347", "ssid": "9e6453dbaf5ffdb03f08812f759d3cdf", "scope": [ "openid", "email", "api1" ], "amr": [ "pwd" ] }
Como você pode ver, o identificador do usuário anônimo (aid) corresponde ao sub do token anônimo, assim como ssid. Se o cliente não iniciou o logon anônimo, o token autenticado conterá apenas ssid.
Assim, podemos autorizar um usuário anônimo e identificar suas ações após entrar no sistema.
Conclusão
Neste artigo, examinamos um cenário para obter um token anônimo / autenticado usando o IdentityServer4 com a extensão AnonymousIdentity .
Se você tiver dúvidas, terei prazer em respondê-las nos comentários.