
最近,我需要在ASP.NET Core平台上基于OpenId Connect和OAuth 2.0实现对匿名用户身份验证的支持。 这些协议的规范将不在此处解释,因为有关Habr的文章全文。 让我们说清楚。
为什么我们需要匿名令牌? 为了授权匿名用户使用API资源,尤其是微服务架构中的匿名用户,他可以更改应用程序的状态,例如Vasya喜欢带猫的T恤,将其添加到在线商店的购物篮中,并有可能以客人的身份下订单。 要了解它是瓦西里(Vasily),匿名令牌包含匿名用户的标识符和会话标识符。 当Vasily登录时,这些参数将包含在经过身份验证的令牌中。
另外,匿名访问令牌可以包含任何其他语句(或声明)。
工具
实作
IdentityServer4在GitHub上有很多示例 。
添加对匿名令牌的支持非常简单:
互动场景
考虑为隐式流和授权码流获取匿名令牌。
授权点请求
为了遵循该规范,对隐式流的授权点的请求如下。
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获取匿名/已认证令牌的方案。
如果您有任何疑问,我将很乐意在评论中回答。