我正在使用AuthorizationCode流将IdentityServer3的实现配置为新客户端应用程序(Salesforce Communities)的身份提供者。一切都按预期工作,直到客户端到达userinfo端点,此时发生以下错误:
ERROR IdentityServer3.Core.Validation.TokenValidator Checking for expected scope openid failed
和
ERROR IdentityServer3.Core.Endpoints.UserInfoEndpointController insufficient_scope
这显然使人们相信客户端没有在授权请求中请求openid作用域,这在使用OpenId Connect时是必需的。但是,我可以确认客户端确实在授权请求中请求了openid范围:
INFO IdentityServer3.Core.Validation.AuthorizeRequestValidator Authorize request validation success
{
"ClientId": "{client_id}",
"ClientName": "{client_name",
"RedirectUri": "{redirect_uri}",
"AllowedRedirectUris": [
"{allowed_uri_which_matches_request}"
],
"SubjectId": "{subject_id}",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid",
"State": "{state_value}",
"SessionId": "402a2356f0bd91a350dfd1f8779ea229",
"Raw": {
"response_type": "code",
"client_id": "{client_id}",
"redirect_uri": "{redirect_uri}",
"scope": "openid",
"state": "{state_value}"
}
}
我还可以确认openid是我的客户端的允许范围,而openid是在ScopeStore中。
此外,当我查看在数据库中生成的令牌时,它们都正确地具有openid范围。 userinfo端点中只有一些导致检查失败的东西。
我对这个问题感到十分困惑,因为这个客户端的实现几乎完全是标准的并且开箱即用。如果它有帮助,我可以提供所有三个请求的完整日志:authorize,token和userinfo。
谢谢!
答案最终出现在DefaultClaimsProvider的自定义覆盖中,特别是在GetAccessTokenClaimsAsync方法中。该方法是手动组装要添加到令牌的声明列表,并方便地忽略openid的范围声明。我们之前的实现如何在没有这种说法的情况下工作是超出我的,但是在将其添加回所有工作顺利之后。