C# 通过oidc客户端登录IdentityServer4时出现InvalidOperationException

C# 通过oidc客户端登录IdentityServer4时出现InvalidOperationException,c#,asp.net-core,vue.js,identityserver4,C#,Asp.net Core,Vue.js,Identityserver4,我在Vue.js+ASP.NET Core 2.1 web应用程序与IdentityServer 4之间运行身份验证流时遇到一些问题,似乎我缺少一些非常基本的东西,但不确定是什么。我想要以下内容: REST API()通过IdentityServer 4进行保护 () 用户打开我的asp.net核心web应用程序 (),单击登录 JavaScript提交配置并使用SignInDirect将浏览器发送到IdentityServer4应用程序 用户输入登录详细信息并提交 浏览器将每个配置重定向到具有

我在Vue.js+ASP.NET Core 2.1 web应用程序与IdentityServer 4之间运行身份验证流时遇到一些问题,似乎我缺少一些非常基本的东西,但不确定是什么。我想要以下内容:

  • REST API()通过IdentityServer 4进行保护 ()
  • 用户打开我的asp.net核心web应用程序 (),单击登录
  • JavaScript提交配置并使用SignInDirect将浏览器发送到IdentityServer4应用程序
  • 用户输入登录详细信息并提交
  • 浏览器将每个配置重定向到具有成功登录详细信息的我的asp.net核心web应用
  • 用户现在可以通过我的asp.net核心web应用程序访问REST API
  • 我可以从我的vue+web app->IdentityServer 4快速启动登录UI获取,它显示以下登录UI:

    我正在使用测试用户帐户“bob”和“alice”,在输入alice的用户id和密码并尝试登录后,出现以下错误:

    处理请求时发生未处理的异常

    InvalidOperationException:为注册的身份验证处理程序 方案“载体”是“IdentityServerAuthenticationHandler”,不能 用于符号同步。注册的登录方案为:idsrv, idsrv.external

    Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext 上下文、字符串方案、ClaimsPrincipal主体、, AuthenticationProperties(属性)

    我的客户端配置为:

    new Client
        {
            ClientId = "js",
            ClientName = "JavaScript Client",
            AllowedGrantTypes = GrantTypes.Implicit,
            AllowAccessTokensViaBrowser = true,
    
            RedirectUris =           { "http://localhost:6666/static/account/callback.html" },
            PostLogoutRedirectUris = { "http://localhost:6666" },
            AllowedCorsOrigins =     { "http://localhost:6666" },
    
            // scopes that client has access to
            AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                "api1"
            }
        }
    
    我的javascript客户端的配置为(TypeScript):

    我的登录javascript代码是:

    public login() {
        this.userManager.signinRedirect();
    }
    
    我感觉我将基于客户端的登录流与自动登录流错误地结合在一起,但我不确定

    ID4的日志基本上与上面的相同:

    System.InvalidOperationException:为方案“承载者”注册的身份验证处理程序是“IdentityServerAuthenticationHandler”,不能用于SignInAsync。注册的登录方案有:idsrv、idsrv.external

    My ID4 startup.cs具有以下条目:

    public void ConfigureServices(IServiceCollection services)
        {
    
            // configure identity server with in-memory stores, keys, clients and scopes
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryClients(Config.GetClients())
                .AddTestUsers(Config.GetUsers());
    
            services.AddMvcCore()
               .AddAuthorization()
               .AddJsonFormatters();
    
            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
    
                    options.ApiName = "api1";
                });
    
            services.AddCors(options =>
            {
                // this defines a CORS policy called "default"
                options.AddPolicy("default", policy =>
                {
                    policy.WithOrigins("http://localhost:6666")
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
            });
    
            services.AddMvc();
    
    }
    

    抱歉,代码转储太长。。。有谁能指出我没有掌握的简单的一点吗?我有一些电线交叉的地方与我需要的身份验证类型和它需要的配置。。。我想…

    好吧,我终于明白了

    DI services.AddAuthentication(“Bearer”)调用将ASP.NET身份验证添加到my IdentityServer4 web app中的Startup.cs,以实现“Bearer”访问令牌验证。但这不是它的正确位置-它应该放在我的API web应用程序中,因为这是API用来验证对它的调用的

    IdentityServer4 web应用程序旨在接受用户id+密码进行身份验证,但在我添加的DI中,它还需要一个承载访问令牌作为身份验证的一部分。这基本上把事情搞砸了,为什么它与登录计划不兼容。我有正确的代码,但在错误的应用程序


    将AddAuthentication(“承载者”)移动到我的API web应用解决了整个问题。

    当您登录IdentityServer时,为什么要设置
    身份验证
    标题?Hi@vasily.sib,我正在遵循IdentityServer 4 Javascript客户端快速启动:流程,该流程将此作为说明的一部分。您指的是代码的这一部分?AddAuthentication(“Bearer”)我可能错了,因为我对IdentityServer4没有太多经验。我刚刚看到,该异常显示“为方案‘Bearer’注册的身份验证处理程序……注册的登录方案是:idsrv,idsrv.external”。所以我假设,您登录到IdentityServer4时,
    Authentication
    头已经设置为某个承载令牌。我想你一定不能寄。嗨@vasily.sib,是的,这看起来像问题!我把那个部分注释掉了,它遵守并成功运行了。登录正常,并成功重定向到目标Url。我一定是从我正在使用的另一个IdentityServer4示例中复制的。非常感谢!如果你想标记最后一个条目,我会勾选它作为答案。我很高兴听到这对你有帮助。但这实际上是一个猜测,我不能肯定地告诉你为什么这个解决方案有效:)所以,我认为这不可能是一个答案。如果有人能更清楚地解释这一点,他们是受欢迎的。
    public void ConfigureServices(IServiceCollection services)
        {
    
            // configure identity server with in-memory stores, keys, clients and scopes
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryClients(Config.GetClients())
                .AddTestUsers(Config.GetUsers());
    
            services.AddMvcCore()
               .AddAuthorization()
               .AddJsonFormatters();
    
            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
    
                    options.ApiName = "api1";
                });
    
            services.AddCors(options =>
            {
                // this defines a CORS policy called "default"
                options.AddPolicy("default", policy =>
                {
                    policy.WithOrigins("http://localhost:6666")
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
            });
    
            services.AddMvc();
    
    }