【问题标题】:IdentityServer4 always returning "error": "invalid_scope"IdentityServer4 总是返回“错误”:“invalid_scope”
【发布时间】:2020-12-02 10:50:18
【问题描述】:

我正在使用 IdentityServer4(4.0.4),但是它不返回 access_token,它总是返回:"error": "invalid_scope"

只需添加以下代码和 Nuget 包 IdentityServer4(4.0.4) 和 IdentityServer4.EntityFramework(4.0.4) 即可重新创建错误。在请求中添加“范围”没有任何区别。

这是从 Postman 触发的端点:

这是我的配置类:

using IdentityServer4;
using IdentityServer4.Models;
using System.Collections.Generic;
using System.Linq;

namespace WebApplication1
{
    public class Config
    {
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("ApiName", "ApiDisplayName")
            };
        }

        public static List<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile() // <-- usefull
            };
        }

        public static IEnumerable<Client> GetClients()
        {
            return new[]
            {
                // for public api
                new Client
                {
                    ClientId = "secret_client_id",
                    AllowedGrantTypes = GrantTypes.ClientCredentials,
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                 AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "ApiName"
                }
            }
        };
    }
}
}

这是我的Startup 班级:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WebApplication1
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentityServer()
             .AddDeveloperSigningCredential()
             .AddOperationalStore(options =>
             {
                 options.EnableTokenCleanup = true;
                 options.TokenCleanupInterval = 30; // interval in seconds
             })
             .AddInMemoryApiResources(Config.GetApiResources())
             .AddInMemoryClients(Config.GetClients())
             .AddInMemoryIdentityResources(Config.GetIdentityResources());
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseIdentityServer();
            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}

【问题讨论】:

    标签: .net asp.net-core .net-core identityserver4 identity


    【解决方案1】:

    仔细检查您的客户端是否正在查看您的 ApiScopes 配置中未配置的范围。在下面的示例中,我的客户注册正在查看“THIS_IS_AN_INVALID_SCOPE”,但我实际上并没有在我的ApiScopes 中定义此范围。

            public static class Scopes
            {
                public static IEnumerable<ApiScope> Get()
                {
                    return new[]
                    {
                        new ApiScope("ProtectedResource.Scope1", "Access to ProtectedResource.Scope1"),
                        new ApiScope("ProtectedResource.Scope2", "Access to ProtectedResource.Scope2")
                    };
                }
            }
    
            public static class Clients
            {
                public static IEnumerable<Client> Get()
                {
                    return new List<Client>
                    {
                        new Client
                        {
                            ClientId = "IntegrationTests",
                            ClientName = "Example client application using client credentials",
                            AllowedGrantTypes = GrantTypes.ClientCredentials,
                            ClientSecrets = new List<Secret> {new Secret("not_the_actual_password".Sha256())},
                            AllowedScopes = new List<string> {"THIS_IS_AN_INVALID_SCOPE"},
                            AccessTokenLifetime = 300 //5 Minutes
                        },
                    };
                }
            }
     
    

    【讨论】:

    • Scopes 类在哪里使用
    【解决方案2】:

    您必须在配置中添加 ApiScope。在最新的 IdentityServer4 中进行了更改 就像这样:

            public static IEnumerable<ApiScope> GetApiScopes()
        {
            return new List<ApiScope>
                 {
                     new ApiScope(name: "read",   displayName: "Read your data."),
                     new ApiScope(name: "write",  displayName: "Write your data."),
                     new ApiScope(name: "delete", displayName: "Delete your data."),
                     new ApiScope(name: "identityserverapi", displayName: "manage identityserver api endpoints.")
                 };
        }
    

    【讨论】:

      【解决方案3】:

      正如@DES PRO 所说,您需要在配置文件中添加 ApiScope,如下所示。

          public static IEnumerable<ApiScope> GetApiScopes()
              {
                  return new List<ApiScope>
                   {
                       new ApiScope(name: "ApiOne")
                   };
              }
      

      然后将作用域添加到 Startup.cs 类中的 ConfigureService。这回答了@raphael 问题“Scopes 类在哪里使用?”

      public void ConfigureServices(IServiceCollection services)
      {
                  services.AddIdentityServer()
                      .AddInMemoryApiResources(Configuration.GetApis())
                      .AddInMemoryClients(Configuration.GetClients())
                      .AddInMemoryApiScopes(Configuration.GetApiScopes())
                      .AddDeveloperSigningCredential();
      
                  services.AddControllersWithViews();
      }
      

      【讨论】:

        【解决方案4】:

        您必须始终包含 openid 范围,因为这是 OpenID-Connect 中必需的范围。

        在 IdentityServer 中,StandardScopes 在这里定义 https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/src/IdentityServerConstants.cs

        但实际上它只是一个字符串。因此,您可以使用“openid”或 IdentityServerConstants.StandardScopes.OpenId

        【讨论】:

        • 那里有IdentityServerConstants.StandardScopes.OpenId
        • 更新了我的答案,希望我的答案可以接受。
        【解决方案5】:

        您需要验证表 ApiScopes 中有什么。

        【讨论】:

          猜你喜欢
          • 2023-02-24
          • 2023-01-20
          • 2012-02-26
          • 2014-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-27
          • 2017-04-24
          相关资源
          最近更新 更多