使用AnonymousIdentity支持IdentityServer4中的匿名jwt令牌


最近,我需要在ASP.NET Core平台上基于OpenId Connect和OAuth 2.0实现对匿名用户身份验证的支持。 这些协议的规范将不在此处解释,因为有关Habr的文章全文。 让我们说清楚。


为什么我们需要匿名令牌? 为了授权匿名用户使用API​​资源,尤其是微服务架构中的匿名用户,他可以更改应用程序的状态,例如Vasya喜欢带猫的T恤,将其添加到在线商店的购物篮中,并有可能以客人的身份下订单。 要了解它是瓦西里(Vasily),匿名令牌包含匿名用户的标识符和会话标识符。 当Vasily登录时,这些参数将包含在经过身份验证的令牌中。


另外,匿名访问令牌可以包含任何其他语句(或声明)。


工具



实作


IdentityServer4在GitHub上有很多示例


添加对匿名令牌的支持非常简单:


  • 使用IdneitityServer4在项目中安装AnonymousIdentity
    Install-Package AnonymousIdentity 
  • 在Startup.cs中注册AnonymousIdentity
     services.AddIdentityServer() //   .AddAnonymousAuthentication(); 

互动场景


考虑为隐式流授权码流获取匿名令牌。


授权点请求


为了遵循该规范,对隐式流的授权点的请求如下。


 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 

对于“ 授权代码流”,具有response_type = code 类似请求(PKCE是可选的)。


常规请求和匿名请求之间的区别在于两个参数:


  • acr_values = 0参数表示匿名登录。 如果有兴趣,您可以阅读OpenId Connect规范。
  • response_mode = json参数用于以Json的形式进行响应,而无需不必要的重定向。

接收令牌


根据身份验证状态,将返回匿名令牌或已认证令牌。


隐式流


在这种情况下,授权点以Json的形式响应,包括访问令牌。


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

授权码流程


使用这种方法,授权点以Json的形式响应,包括授权代码。


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

然后,您需要使用标准方法来交换令牌的代码。


我们向令牌的端点提出请求。


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

结果,令牌端点以Json的形式响应,包括访问令牌。


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

比较匿名和认证令牌


如果授权服务器不包含身份验证数据,我们将获得一个匿名令牌。


 { "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" ] } 

您可以使用身份验证方法(amr)确定用户是匿名的。
在随后的用户登录时,“常规”会话的标识符(ssid)和主题(sub)的标识符将包括在经过身份验证的令牌中。


如果用户登录,我们将获得经过身份验证的令牌。


 { "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" ] } 

如您所见,匿名用户标识符(aid)与匿名令牌的子项匹配,就像ssid一样。 如果客户端未启动匿名登录,则经过身份验证的令牌将仅包含ssid。


因此,我们可以授权匿名用户并在进入系统后识别其行为。


结论


在本文中,我们研究了使用带有AnonymousIdentity扩展名的IdentityServer4获取匿名/已认证令牌的方案。


如果您有任何疑问,我将很乐意在评论中回答。

Source: https://habr.com/ru/post/zh-CN466467/


All Articles