在使用ASP.NET Core中的JavaScript客户端时,在Identity Server 4中获取范围验证错误

38

当我从我的Javascript客户端应用程序向我的Identity Server应用程序发出请求时,我收到了以下错误:

fail: IdentityServer4.Validation.ScopeValidator[0] Invalid scope: openid

我已经确保在我的Identity Server应用程序中添加了该范围。以下是我的代码。

IdentityServer应用程序(主机) Config.cs

  public class Config
{
    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource("api1","My API")
        };
    }

    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        {
            new Client
            {
                 ClientId = "js",
                 ClientName = "javaScript Client",
                 AllowedGrantTypes = GrantTypes.Implicit,
                 AllowAccessTokensViaBrowser = true,
                 RedirectUris = { "http://localhost:5003/callback.html" },
                 PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
                 AllowedCorsOrigins = { "http://localhost:5003" },
                 AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "api1"
                    }
            }
        };
    }
}

Startup.cs

  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 http://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddIdentityServer()
            .AddTemporarySigningCredential()
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients());
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseIdentityServer();
        }

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
}

Web API启动类Startup.cs

 public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsEnvironment("Development"))
        {
            // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
            builder.AddApplicationInsightsSettings(developerMode: true);
        }

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);

        services.AddCors(option =>
        {
            option.AddPolicy("dafault", policy =>
            {
                policy.WithOrigins("http://localhost:5003")
                      .AllowAnyHeader()
                      .AllowAnyMethod();
            });
        });
        services.AddMvcCore()
                .AddAuthorization()
                .AddJsonFormatters();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        //this uses the policy called "default"
        app.UseCors("default");

        app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://localhost:5000",
            AllowedScopes = { "api1" },
            RequireHttpsMetadata = false
        });

        app.UseApplicationInsightsRequestTelemetry();

        app.UseApplicationInsightsExceptionTelemetry();

        app.UseMvc();
    }
}

我在按照文档中的示例操作时遇到了相同的错误。你有什么好的解决方法吗? - alessalessio
2个回答

68

当你的客户端(应用程序)被配置或允许请求openid资源(或范围),你的身份服务器没有配置openid身份资源。

你需要将它添加为一个身份资源,类似于这里所示,并且有一个方法返回你想要使用的所有身份资源,就像这里所做的

简单来说,在Config.cs中添加一个新的方法,看起来像这样:

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

然后在您的 IdentityServer 服务容器中添加您的身份资源配置,如下所示:

 services.AddIdentityServer()
    .AddTemporarySigningCredential()
    .AddInMemoryApiResources(Config.GetApiResources())
    .AddInMemoryClients(Config.GetClients())
    .AddInMemoryIdentityResources(Config.GetIdentityResources()); // <-- adding identity resources/scopes

1
现在它正在工作,但是现在它显示“显示登录:用户未经身份验证”。 - maxspan
IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator[0] 显示用户未经过身份验证。我该如何对用户进行身份验证? - maxspan
1
是的,我正在使用JavaScript应用程序。文档中有示例。 - maxspan
1
@AdamMendoza 我修复了链接。 - Lutando
2
我曾遇到类似的错误,但我是通过添加“AddInMemoryApiScopes”在“ConfigureServices”中修复了它。 - Alejandro B.
显示剩余9条评论

4
在我的情况下,这是由于缺少对 .AddInMemoryApiScopes() 的调用引起的,通过在调试器下检查下面的返回值(特别是 ErrorHttpStatusCode 字段表明 无效的作用域,正如您所报告的),可以看出这是从一个简单的控制台应用程序中发生的。
await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest { ... });

为了解决这个问题,我在自定义配置类中添加了以下方法。
public static IEnumerable<ApiScope> Scopes
{
    get
    {
        return new List<ApiScope> 
        { 
            new ApiScope("my-scope-name", "Friendly scope name") 
        };
    }
}

然后从 Startup.ConfigureServices() 中调用它。

    services.AddIdentityServer()
        .AddInMemoryApiResources(Configuration.Apis)
        .AddInMemoryClients(Configuration.Clients)
        .AddInMemoryApiScopes(Configuration.Scopes);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接