【问题标题】:Identity Server 4 create client with IConfigurationIdentity Server 4 使用 IConfiguration 创建客户端
【发布时间】:2018-12-04 19:39:08
【问题描述】:

我将身份服务器的 clients 存储在 appsettings.json 文件中:

"ClientSettings":  [
{
  "ClientId": "TestClient1",
  "RedirectUris": [ "http://localhost:5002/signin-oidc" ],
  "PostLogoutRedirectUris": [ "http://localhost:5002/signout-callback-oidc" ],
  "AllowedGrantTypes": [ "hybrid" ],
  "AllowedScopes": [ "openid","profile","email" ],
  "RequireConsent": "false",
  "Enabled": "true",
  "ClientSecrets": [
    {
      "Description": "This is the client sceret description.",
      "Value": "password123"
    }
  ]
}
],

在我的 ConfigureServices 方法中,我设置了依赖注入

services.Configure<List<Client>>(config.GetSection("ClientSettings"));

我的IClientStore 通过依赖注入获取客户端列表。当然,我需要散列客户端密码。为了让这个问题保持简单,我编写了这段代码,假设我只有一个客户端和一个客户端密码。

public ClientConfigFileStore(IOptions<List<Client>> options)
{
    var jsonClient = options.Value[0];
    Client client = new Client()
    {
        ClientId = jsonClient.ClientId,
        RedirectUris = jsonClient.RedirectUris,
        PostLogoutRedirectUris = jsonClient.PostLogoutRedirectUris,
        AllowedGrantTypes = jsonClient.AllowedGrantTypes,
        AllowedScopes = jsonClient.AllowedScopes,
        RequireConsent = jsonClient.RequireConsent,
        Enabled = jsonClient.Enabled,
    };//Works
    Client client = jsonClient;//Does not work

    client.ClientSecrets = new List<Secret>()
    {
        new Secret(jsonClient.ClientSecrets.First().Value.Sha256())
    };
    clients = new List<Client>() { client };
}

不知何故,我需要创建Client 的新实例,并且使用依赖注入创建的实例不起作用。用户在身份服务器上输入他的凭据后,重定向回客户端失败并显示Client secret validation failed for the client: TestClient1

为什么需要创建一个新实例,是否有更优雅的方式从appsettings.json 文件加载客户端?

【问题讨论】:

  • 你为什么要从那个文件中加载它们?为什么不给它自己的文件呢?
  • 我也可以这样做,而且会更有条理。但这并不能解决问题?
  • 你为什么不只使用 AddInMemoryClients?我想我不明白你为什么要这样做,你到底想做什么。
  • 我想要一种简单的方法来调整客户端设置。在使用AddInMemoryClients 时调整设置时,需要发布新版本的身份服务器。
  • 这就是它的工作原理。我认为您不能即时将新客户端添加到内存中。如果您希望能够像这样添加它们,您应该将它们放在数据库中。我将深入研究代码,看看是否有办法在运行中添加内存客户端。

标签: c# authentication asp.net-core dependency-injection identityserver4


【解决方案1】:

我不确定我是否理解您想要做什么或为什么要这样做。主要是我不确定你为什么要像你一样在 DI 中加载它们。您应该考虑在内存客户端中使用。

startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        // configure identity server with in-memory stores, keys, clients and scopes
        services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients());
    }

config.cs

public class Config
{
    // scopes define the API resources in your system
    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource("api1", "My API")
        };
    }

    // clients want to access resources (aka scopes)
    public static IEnumerable<Client> GetClients()
    {
        // client credentials client
        return new List<Client>
        {
            new Client
            {
                ClientId = "client",
                AllowedGrantTypes = GrantTypes.ClientCredentials,

                ClientSecrets = 
                {
                    new Secret("secret".Sha256())
                },
                AllowedScopes = { "api1" }
            }
        };
    }
}

来自quickstart identityserver的代码

【讨论】:

  • 你对内存中的方法是正确的。我编辑了你的答案以满足我的需要,以防其他人有类似的问题。我更喜欢从 *.json 文件加载客户端,而不是硬编码它们。这也从代码库中删除了秘密。即使我仍然不知道为什么这种转换(或创建新实例并复制)有效,而另一种方法则无效。
【解决方案2】:

将您的客户机密部分更改为:

"ClientSecrets": [
      {
        "Value": "<Sha256 hash of secret>",
        "Type": "SharedSecret"
      }
 ],

【讨论】:

    猜你喜欢
    • 2019-07-25
    • 2020-03-22
    • 2020-01-11
    • 2021-08-07
    • 2019-06-06
    • 2019-02-15
    • 2020-04-10
    • 1970-01-01
    • 2019-12-04
    相关资源
    最近更新 更多