简体   繁体   English

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

[英]InvalidOperationException when signing in to IdentityServer4 via oidc-client

I'm having some problems getting my authentication flow working between a Vue.js + ASP.NET Core 2.1 web app with IdentityServer4, seems I'm missing something very basic but not sure what. 我在使我的身份验证流程在带有IdentityServer4的Vue.js + ASP.NET Core 2.1 Web应用程序之间工作时遇到了一些问题,似乎我缺少了一些非常基本的内容,但不确定是什么。 I want to have the following: 我想要以下内容:

  1. REST APIs ( http://localhost:7000 ) are secured via IdentityServer4 ( http://localhost:5000 ) REST API( http:// localhost:7000 )通过IdentityServer4( http:// localhost:5000 )保护。
  2. User opens up my asp.net core web app ( http://localhost:6666 ), clicks login 用户打开我的asp.net核心Web应用程序( http:// localhost:6666 ),单击登录
  3. JavaScript submits config and uses signinredirect to send browser to IdentityServer4 app JavaScript提交配置并使用signinredirect将浏览器发送到IdentityServer4应用
  4. User enters login details and submits 用户输入登录详细信息并提交
  5. Browser redirects per configuration to my asp.net core web app with successful login details 浏览器根据成功的登录详细信息将每个配置重定向到我的asp.net核心Web应用
  6. User can now access REST APIs via my asp.net core web app 用户现在可以通过我的asp.net核心网络应用访问REST API

I can get from my vue+web app -> IdentityServer4 quickstart logon UI, and it presents the following login UI: 我可以从我的vue + Web应用程序-> IdentityServer4 quickstart登录UI中获得,它显示以下登录UI:

IdentityServer4 Quickstart UI IdentityServer4快速入门UI

I am using the test user accounts "bob" and "alice", after putting in the user id and password for alice and trying to log in, I get the following error: 我使用测试用户帐户“ bob”和“ alice”,在输入了爱丽丝的用户标识和密码并尝试登录后,出现以下错误:

An unhandled exception occurred while processing the request. 处理请求时发生未处理的异常。

InvalidOperationException: The authentication handler registered for scheme 'Bearer' is 'IdentityServerAuthenticationHandler' which cannot be used for SignInAsync. InvalidOperationException:为方案“ Bearer”注册的身份验证处理程序为“ IdentityServerAuthenticationHandler”,不能用于SignInAsync。 The registered sign-in schemes are: idsrv, idsrv.external. 已注册的登录方案为:idsrv,idsrv.external。

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

My Client configuration is: 我的客户端配置为:

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"
        }
    }

Configuration for my javascript client is (TypeScript): 我的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;

and my login javascript code is: 而我的登录JavaScript代码是:

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

I get the feeling I am incorrectly combining a client-based login flow with an automated sign-on flow, but I'm not sure... 我感到我将基于客户端的登录流程与自动登录流程错误地结合在一起,但是我不确定...

The logs from ID4 say the same as above basically: 来自ID4的日志基本上与上述内容相同:

System.InvalidOperationException: The authentication handler registered for scheme 'Bearer' is 'IdentityServerAuthenticationHandler' which cannot be used for SignInAsync. System.InvalidOperationException:为方案“ Bearer”注册的身份验证处理程序为“ IdentityServerAuthenticationHandler”,不能用于SignInAsync。 The registered sign-in schemes are: idsrv, idsrv.external. 已注册的登录方案为:idsrv,idsrv.external。

My ID4 startup.cs has this entry: 我的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();

}

Sorry about the long code dump... can anyone point out the easy bit I haven't got right? 抱歉,代码转储时间太长...谁能指出我不太正确的容易之处? I have got some wires crossed somewhere with the type of authentication I need and the configuration it requires... I think... 我在某些地方与所需的身份验证类型和所需的配置交叉了...我认为...

OK, I've figured it out finally. 好的,我终于知道了。

The DI services.AddAuthentication("Bearer") call added the ASP.NET Authentication to Startup.cs in my IdentityServer4 web app, in order to implement "Bearer" access token validation. DI services.AddAuthentication(“ Bearer”)调用将ASP.NET Authentication添加到我的IdentityServer4 Web应用程序中的Startup.cs中,以实现“ Bearer”访问令牌验证。 But this isn't the right spot for it - it should have been in my API web app instead, as this is what the API is meant to use to authenticate calls made to it. 但这不是正确的位置-应该在我的API网络应用程序中,因为这是API用来验证对其调用的身份。

The IdentityServer4 web app is meant to accept user id + password for authentication, but with the DI I had added it was also requiring a Bearer access token as part of the authentication. IdentityServer4 Web应用程序旨在接受用户ID +密码进行身份验证,但是在我添加的DI中,它还需要Bearer访问令牌作为身份验证的一部分。 That basically messed up things, and why it was incompatible with the sign-in scheme. 这基本上弄乱了事情,以及为什么它与登录方案不兼容。 I had the right code, but in the wrong app! 我有正确的代码,但在错误的应用程序中!

Moving the AddAuthentication("Bearer") to my API web app resolved the whole issue. 将AddAuthentication(“ Bearer”)移到我的API Web应用程序可以解决整个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM