首页 > 解决方案 > 在 ASP.Net web api 中使用 IdentityServer3.AccessTokenValidation 与 IDS4 对话

问题描述

我们已经使用 .Net Core 2.1 设置了身份服务器 4。我们在 .Net 4.6 上有 ASP.Net Web API。这不能迁移到核心。我已经在这个 API 项目中安装了 IdentityServer3.AccessTokenValidation 以及 OWN 和其他需要的包。我可以使用客户端并从 IdentityServer 获取访问令牌。当客户端将该令牌与 API 一起使用时,我得到 401。我在网上搜索了解决方案,但找不到任何可以用来完成这项工作的东西。我试过这个 - https://github.com/IdentityServer/IdentityServer3.AccessTokenValidation/issues/164 但没有奏效。我找不到任何样品。所以我的问题是不能使用 IdentityServer3.AccessTokenValidation 与 IDS4 交谈吗?

我需要设置 IDS3 吗?

更新

我打开详细日志记录并得到以下信息

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST http://localhost:44333/connect/introspect application/x-www-form-urlencoded 70
IdentityServer4.Hosting.IdentityServerMiddleware:Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.IntrospectionEndpoint for /connect/introspect
IdentityServer4.Validation.ApiSecretValidator:Error: API validation failed.
IdentityServer4.Endpoints.IntrospectionEndpoint:Error: API unauthorized to call introspection endpoint. aborting.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 26.5186ms 401 
Microsoft.AspNetCore.Server.Kestrel:Information: Connection id "0HLIJ2C0UKBLN", Request id "0HLIJ2C0UKBLN:00000008": the application completed without reading the entire request body.

以下是我在配置方法中的 API 代码

        var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();

        app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = "https://localhost:44333",
            RequiredScopes = new[] { "api" },

            ClientId = "api",
            ClientSecret = "secret",

            //DelayLoadMetadata = true
        });

        app.UseWebApi(config);

ApiResource 的 IDS4 端代码。

    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource("api", "MyApi") { ApiSecrets = { new Secret("secret".Sha256()) } }
        };
    }

更新 2

是的,我启用了 Trace。在更多地使用代码并重新安装软件包之后,我现在得到了一个不同的错误。请求已发送到 /connect/accesstokenvalidation。此端点在 IDS4 中不可用

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: 请求开始 HTTP/1.1 POST http://localhost:44333/connect/accesstokenvalidation application/x-www-form-urlencoded 70 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information :请求在 3.405 毫秒内完成 404 Microsoft.AspNetCore.Server.Kestrel:信息:连接 id “0HLIJ9RBG591K”,请求 id “0HLIJ9RBG591K:0000000A”:应用程序在未读取整个请求正文的情况下完成。

标签: asp.net-coreasp.net-web-api2identityserver4identityserver3

解决方案


我花了几天时间解决一个问题,所以我想我会在我的发现中添加一个答案。我正在使用 IDS4 和 .net 4.7 web api。

验证作为 .net 4.7 应用程序的客户端“API”时的主要痛点,使用 IdentityServer4 dotnet 核心令牌服务器进行身份验证。问题是这样的。

.net 4.7 Web API项目的Startup.cs中设置的ClientID和ClientSecret是API Resource的ID和Secret。

首先,您点击 IDS4 /token 端点以获取令牌。该请求需要在 IDS4 项目的 Config.cs 文件中设置的 client_id 和 client_secret(以及其他必需的值)。

  public static IEnumerable<ApiResource> Apis =>
        new ApiResource[]
        {
            new ApiResource("api", "My DotNet 4.7 API"){ //.net 4.7 API clientId
                ApiSecrets = new List<Secret>()
                {
                    new Secret("secret".Sha256())      //.net 4.7 API client secret
                },
                Scopes = { "api"}
            }
        };

       public static IEnumerable<Client> Clients =>
        new Client[]
        {
           new Client
            {
                ClientId = "client",

              ...

                // secret for authentication
                ClientSecrets =
                {
                    new Secret("secret1".Sha256())
                },

              ...
            }
        };

现在使用该令牌,您将其传递给 .net 4.7 Api 端点。这是我得到“401 UnAuthorized”的地方。解决方案在“启动”文件中,特别是这部分:

       app.UseIdentityServerBearerTokenAuthentication(
            new IdentityServerBearerTokenAuthenticationOptions
            {
                .....
                
                //this is the API Resource Id and Secret for that API resource
                ClientSecret = "secret",
                ClientId = "api"
            });

由于某种原因,我不清楚我必须在 API 的配置中使用 API 资源值。现在这是有道理的。但是由于某种原因,我准备的资源都没有专门指出这一点。


推荐阅读