为什么在IdentityServer4';什么是同意屏幕?

为什么在IdentityServer4';什么是同意屏幕?,identityserver4,Identityserver4,我正在编写一个IdentityServer4实现,并使用所描述的快速启动项目 定义ApiResource(目前使用InMemory类)时,IdentityServer会创建一个与资源同名的作用域。比如说 public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource("api", "My API

我正在编写一个IdentityServer4实现,并使用所描述的快速启动项目

定义ApiResource(目前使用InMemory类)时,IdentityServer会创建一个与资源同名的作用域。比如说

public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("api", "My API")
    };
}
为什么会这样?我是不是做错了什么

更新: 这里是发现文档的一部分,显示范围只列出一次


问题似乎出在快速启动UI上。。。或者使用
Scope.cs
类,具体取决于您如何看待它。具体来说,在类中显示的方法和行中

下面的代码

vm.ResourceScopes = resources.ApiResources.SelectMany(x => x.Scopes).Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();

没有筛选出重复项。也就是说,即使两个作用域具有相同的名称,它们也不会被视为相等。因此,如果
GetHashCode
Equals
Scope.cs
中被重写(在IdentityServer4中,而不是快速启动中),那么它将解决此问题。在这种情况下,SelectMany将返回一个唯一的集合。这是因为ApiResources属性是作为哈希集实现的。或者,您可以编写自己的逻辑,使此返回成为一组唯一的作用域。这就是我解决问题的方法。我写了一些与Jon Skeet的答案非常相似的东西,过滤掉了重复的作用域。

看起来问题在于快速启动UI。。。或者使用
Scope.cs
类,具体取决于您如何看待它。具体来说,在类中显示的方法和行中

下面的代码

vm.ResourceScopes = resources.ApiResources.SelectMany(x => x.Scopes).Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();

没有筛选出重复项。也就是说,即使两个作用域具有相同的名称,它们也不会被视为相等。因此,如果
GetHashCode
Equals
Scope.cs
中被重写(在IdentityServer4中,而不是快速启动中),那么它将解决此问题。在这种情况下,SelectMany将返回一个唯一的集合。这是因为ApiResources属性是作为哈希集实现的。或者,您可以编写自己的逻辑,使此返回成为一组唯一的作用域。这就是我解决问题的方法。我写了一些类似于JonSkeet的答案,因为它过滤了重复的作用域。

有一个错误在1.5中被修复,它解决了这个问题:。请升级,看看这是否为您解决了问题。谢谢。

在1.5中刚刚修复了一个bug,它解决了以下问题:。请升级,看看这是否为您解决了问题。谢谢。

问题出在MemoryResourceStore.FindApiResourcesByScopeAsync中的
实现中的IdentityService4代码中,已通过此代码修复。您可以使用
dev
分支,该分支自2017年6月22日起就包括在内,但它从未在任何针对.NET标准1.4的NuGET软件包中发布过,这非常烦人

我创建了一个问题并请求对其进行修补:

为了修复视图,我将标有Todo的行添加到
approverservice.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个不需要的作用域副本。但至少在修复之前它是可用的。

问题在于MemoryResourceStore.FindApiResourcesByScopeAsync中的
实现中的IdentityService4代码,并通过此代码得到了修复。您可以使用
dev
分支,该分支自2017年6月22日起就包括在内,但它从未在任何针对.NET标准1.4的NuGET软件包中发布过,这非常烦人

我创建了一个问题并请求对其进行修补:

为了修复视图,我将标有Todo的行添加到
approverservice.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个不需要的作用域副本。但至少在修复之前它是可用的。

您有多少API资源?它们的作用域将被复制。请考虑从您的<代码> /.NeX/OpenID配置端点发布<代码> StopeSistBuffy/<代码>内容。@ IlyaChumakov我发布了它。我肯定只有一个API资源,所以我不知道为什么会发生这样的事情:您有多少API资源?它们的作用域将被复制。请考虑从您的<代码> /.NeX/OpenID配置端点发布<代码> StopeSistBuffy/<代码>内容。@ IlyaChumakov我发布了它。我肯定只有一个API资源,所以我对为什么会发生这样的事情感到迷惘。至于QS界面,请随时发送PR来解决问题。谢谢。至于QS UI,请随时发送PR以解决问题。