Soporte para tokens jwt anónimos en IdentityServer4 usando AnonymousIdentity


Recientemente, necesitaba implementar soporte para la autenticación anónima de usuarios basada en OpenId Connect y OAuth 2.0 en la plataforma ASP.NET Core. La especificación de estos protocolos no se explicará aquí, para esto hay artículos completos sobre el Habr. Vayamos al grano.


¿Por qué necesitamos un token anónimo? Para autorizar a un usuario anónimo en un recurso API, especialmente en la arquitectura de microservicios, además, puede cambiar el estado de nuestra aplicación, por ejemplo, a Vasya le gustó una camiseta con gatos, la agrega a la cesta de la tienda en línea y, posiblemente, hace un pedido como invitado. Para comprender que fue Vasily, el token anónimo contiene el identificador del usuario anónimo y el identificador de sesión. Cuando Vasily inicia sesión, estos parámetros se incluirán en el token autenticado.


Además, un token de acceso anónimo puede contener declaraciones adicionales (o reclamos).


Las herramientas



Implementación


IdentityServer4 tiene muchos ejemplos en GitHub.


Agregar soporte para tokens anónimos es bastante simple:


  • Instale AnonymousIdentity en un proyecto con IdneitityServer4
    Install-Package AnonymousIdentity 
  • Registre AnonymousIdentity en Startup.cs
     services.AddIdentityServer() //   .AddAnonymousAuthentication(); 

Escenario de interacción


Considere obtener un token anónimo para Flujo implícito y Flujo de código de autorización .


Solicitud de punto de autorización


Para seguir la especificación, una solicitud de un punto de autorización para Flujo implícito es la siguiente.


 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 el flujo de código de autorización, una solicitud similar con response_type = code (PKCE es opcional).


Las diferencias entre una solicitud regular y anónima en dos parámetros:


  • El parámetro acr_values ​​= 0 señala el inicio de sesión anónimo. Si está interesado, puede leer la especificación OpenId Connect .
  • El parámetro response_mode = json se usa para responder en forma de Json sin redireccionamientos innecesarios.

Recibiendo token


Dependiendo del estado de autenticación, se devuelve un token anónimo o autenticado.


Flujo implícito


En este caso, el punto de autorización responde en forma de Json, incluido el token de acceso.


 { "id_token": <id_token>, "access_token": <access_token>, "token_type": "Bearer", "expires_in": "2592000", "scope": "openid email api1", "state": "abc", "session_state": <optional> } 

Flujo de código de autorización


Con este enfoque, el punto de autorización responde en forma de Json, incluido el código de autorización.


 { "code": <authorization_code>, "scope": "openid email api1", "state": "abc", "session_state": <optional> } 

Luego, debe intercambiar el código del token utilizando el método estándar.


Formamos una solicitud al punto final del token.


 POST /connect/token client_id=client2& client_secret=secret& grant_type=authorization_code& code=`& redirect_uri=https://myapp/callback 

Como resultado, el punto final del token responde en forma de Json, incluido el token de acceso.


 { "id_token": <id_token>, "access_token": <access_token>, "token_type": "Bearer", "expires_in": "2592000", "scope": "openid email api1" } 

Comparación de tokens anónimos y autenticados


Si el servidor de autorización no contiene datos de autenticación, obtenemos un 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" ] } 

Puede determinar que el usuario es anónimo utilizando el método de autenticación (amr).
El identificador de la sesión "general" (ssid) y el identificador del sujeto (sub) se incluirán en el token autenticado, en el siguiente inicio de sesión del usuario.


En caso de que el usuario haya iniciado sesión, obtenemos un 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 puede ver, el identificador del usuario anónimo (ayuda) coincide con el sub del token anónimo, al igual que ssid. Si el cliente no inició el inicio de sesión anónimo, el token autenticado contendrá solo ssid.


Por lo tanto, podemos autorizar a un usuario anónimo e identificar sus acciones después de ingresar al sistema.


Conclusión


En este artículo, examinamos un escenario para obtener un token anónimo / autenticado usando IdentityServer4 con la extensión AnonymousIdentity .


Si tiene preguntas, con gusto las responderé en los comentarios.

Source: https://habr.com/ru/post/466467/


All Articles