c# - 通过 oidc-client 登录 IdentityServer4 时出现 InvalidOperationException

标签 c# asp.net-core vue.js identityserver4

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

  1. REST API ( http://localhost:7000 ) 通过 IdentityServer4 进行保护 ( http://localhost:5000 )
  2. 用户打开我的 ASP.NET Core Web 应用程序 (http://localhost:6666),点击登录
  3. JavaScript 提交配置并使用signinredirect 将浏览器发送到 IdentityServer4 应用
  4. 用户输入登录详细信息并提交
  5. 浏览器将每个配置重定向到我的 ASP.NET Core Web 应用程序并提供成功的登录详细信息
  6. 用户现在可以通过我的 asp.net core Web 应用访问 REST API

我可以从我的 vue+web 应用程序 -> IdentityServer4 快速启动登录 UI 中获取,它呈现以下登录 UI:

IdentityServer4 Quickstart UI

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

An unhandled exception occurred while processing the request.

InvalidOperationException: The authentication handler registered for scheme 'Bearer' is 'IdentityServerAuthenticationHandler' which cannot be used for SignInAsync. The registered sign-in schemes are: idsrv, idsrv.external.

Microsoft.AspNetCore.Authentication.AuthenticationService.SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)

我的客户端配置是:

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):

// Authentication init code
idConfig: Oidc.UserManagerSettings = {
    authority: "http://localhost:5000",
    client_id: "js",
    redirect_uri: "http://localhost:6666/static/account/callback.html",
    response_type: "id_token token",
    scope: "openid profile castlepoint",
    post_logout_redirect_uri: "http://localhost:6666",
} as Oidc.UserManagerSettings;

我的登录 JavaScript 代码是:

public login() {
    this.userManager.signinRedirect();
}

我感觉我错误地将基于客户端的登录流程与自动登录流程结合在一起,但我不确定......

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

System.InvalidOperationException: The authentication handler registered for scheme 'Bearer' is 'IdentityServerAuthenticationHandler' which cannot be used for SignInAsync. The registered sign-in schemes are: idsrv, idsrv.external.

我的 ID4startup.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 身份验证添加到我的 IdentityServer4 Web 应用程序中的 Startup.cs,以实现“Bearer”访问 token 验证。但这不是它的正确位置 - 它应该位于我的 API Web 应用程序中,因为这是 API 用来验证对其进行的调用的。

IdentityServer4 Web 应用程序旨在接受用户 ID + 密码进行身份验证,但使用我添加的 DI,它还需要不记名访问 token 作为身份验证的一部分。这基本上把事情搞砸了,以及为什么它与登录方案不兼容。我有正确的代码,但在错误的应用程序中!

将 AddAuthentication("Bearer") 移至我的 API Web 应用程序解决了整个问题。

关于c# - 通过 oidc-client 登录 IdentityServer4 时出现 InvalidOperationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51016177/

相关文章:

c# - Winforms 以另一种形式创建 2 种形式的实例

c# - 属性只能由序列化程序设置

c# - 在 linq 中添加带有计数函数的额外列以进行查询?

asp.net-core - 在 Razor View 中注入(inject) Controller 与注入(inject)服务

javascript - 如何从一堆计算值中逐个分配 Vue 对象的属性?

javascript - import { Component, Vue } from "vue-property-decorator"与 import Vue from "vue"

c# - 动态创建类而不是使用开关 block 的最佳方法

c# - .Net Core Connection 目前有事务登记

amazon-web-services - AWS .NET Core Lambda - 图像上传损坏

javascript - 在 Vue.js/Vue-select 的选项属性中检索数据变量