我正在编写IdentityServer4实现并使用描述为here的快速入门项目。
定义ApiResource(现在使用InMemory类)时,IdentityServer看起来像创建一个与资源同名的Scope。例如
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api", "My API")
};
}
将创建一个名为&#34; api&#34; (这是在ApiResource构造函数中完成的)。如果我添加&#34; api&#34;作为我的Client对象上的允许范围(使用InMemoryClients进行概念验证)并在我的JavaScript客户端的auth请求中的范围查询字符串参数中请求此api Scope我收到invalid_scope错误消息。
我通过跟随this documentation发现你可以通过Scopes属性将范围添加到ApiResource,如此
new ApiResource
{
Name = "api",
DisplayName = "Custom API",
Scopes = new List<Scope>
{
new Scope("api.read"),
new Scope("api.write")
}
}
所以现在如果我改为像这样定义我的ApiResource并请求Scopes api.read和api.write(并将它们添加到客户端对象上的AllowedScopes属性),那么一切正常,除了显示重复范围的同意页面。它显示api.read 2次,api.write 2次。请参见此处的同意屏幕
客户端配置如下:
new Client
{
ClientId = "client.implicit",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:3000/health-check" },
PostLogoutRedirectUris = { "http://localhost:3000" },
AllowedCorsOrigins = { "http://localhost:3000" },
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"customApi.read", "customApi.write"
}
}
为什么会这样?我做了一件明显不对的事吗?
更新 这里显示范围的发现文档的一部分仅列出一次......
答案 0 :(得分:2)
看起来问题出在Quickstart UI上,或者storage\app\public
类,这取决于你如何看待它。具体而言,在类ConsentService.cs
以下代码
Scope.cs
没有过滤掉重复项。也就是说,即使两个Scope具有相同的名称,它们也不被认为是相同的。因此,如果vm.ResourceScopes = resources.ApiResources.SelectMany(x => x.Scopes).Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();
和GetHashCode
在Equals
(在IdentityServer4中,而不是快速入门)中被覆盖,那么它将解决此问题。在这种情况下,SelectMany将返回一个唯一的集合。这是因为ApiResources属性是作为HashSet实现的。或者,您可以编写自己的逻辑,以使其返回一组唯一的范围。这就是我解决问题的方法。我写了一些与Jon Skeet在this post中的答案非常类似的东西,它过滤掉了重复的范围。
答案 1 :(得分:1)
问题在于InMemoryResourcesStore.FindApiResourcesByScopeAsync
实现中的IdentityService4代码,并且已使用此commit修复。您可以使用自2017年6月22日起包含的dev
分支,但它从未在任何针对.NET Standard 1.4的NuGET包中发布,这非常令人讨厌。
我创建了一个问题,并要求修补它: https://github.com/IdentityServer/IdentityServer4/issues/1470
为了修复视图,我将标有Todo的行添加到ConsentService.cs
var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.ScopesRequested);
if (resources != null && (resources.IdentityResources.Any() || resources.ApiResources.Any()))
{
// TODO: Hotfix to cleanup scope duplication:
resources.ApiResources = resources.ApiResources.DistinctBy(p => p.Name).ToList();
return CreateConsentViewModel(model, returnUrl, request, client, resources);
}
这解决了显示问题,但范围仍将在访问令牌中多次包含,这使得它更大,因为它平方化该API的范围计数。我有3个范围,因此每个范围包含3次,添加了6个不需要的范围副本。但至少在它得到解决之前它是可用的。
答案 2 :(得分:0)
在1.5中修复了一个错误,解决了这个问题:https://github.com/IdentityServer/IdentityServer4/pull/1030。请升级,看看是否能解决问题。感谢。