【问题标题】:Best practice on multiple IdentityServer4 services多个 IdentityServer4 服务的最佳实践
【发布时间】:2020-11-25 22:12:41
【问题描述】:

我有两个身份服务器和一个 Web API。 我试图做的是让 API 对一个或两个 IdentityServers 进行身份验证,并且能够在其中一个发生故障时进行切换。如果可能的话,我还希望能够在运行时添加一个新的 IdentityServer。

这里有什么最佳实践吗?

目前看起来是这样的。

        app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = $"http://localhost:5000",
            ScopeName = "my.scope",
            RequireHttpsMetadata = false,
            ScopeSecret = "secret",
        });

如果我在端口 5000 处关闭 IdentityServer,我将无法再使用 API。这是意料之中的。

【问题讨论】:

  • 您应该在负载均衡器后面有冗余的身份服务器。然后网络会处理这个问题。
  • 我制作了一个非常简单的中间件,它将 localhost:5000 上的调用重新路由到正确的身份服务器。这很好用..一次(?)。之后,他直接进入身份服务器并忽略我设置的权限。他会在运行时更新 athority 吗?
  • 如果其中一个调用超时,我能否以某种方式告诉他重试授权?即使我现在实现了正确的负载均衡器,它仍然会具有相同的行为,因为 IdentityServer 会告诉要使用哪些地址。所以在初始调用之后的所有调用都将绕过负载均衡器。我不介意这个。但如果可能的话,如果 IdentityServer 出现故障,我想重试。截至目前,API 将与 IdentityServer 一起消失,即使使用负载均衡器也是如此。

标签: .net-core identityserver4


【解决方案1】:

我不确定这是否是解决问题的好方法。但这是一种方式。 我向我的路由服务询问“第一个身份服务”以在选项中设置权限。 然后我添加了一个自定义 IntrospectionBackChannelHandler

        app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = $"http://{v.Address}:{v.Port}",
            IntrospectionBackChannelHandler = new CustomIntrospectionBackChannelHandler(consulService)

由于我所有的身份服务器看起来都一样,但地址不同,我真的不必费心再做一次权威的事情。

在自定义的 Introspect 中......我检查每个 introspect 并将其发送到“正确的”身份服务器。如果它不起作用,我尝试另一个身份服务器。

var qs = 等待 request.Content.ReadAsStringAsync(); var queryDic = QueryHelpers.ParseQuery(await request.Content.ReadAsStringAsync());

        var token = queryDic["token"];
        var client_id = queryDic["client_id"];
        var client_secret = queryDic["client_secret"];
        var iRequest = new IntrospectionRequest
        {
            ClientId = client_id,
            ClientSecret = client_secret,
            TokenTypeHint = "access_token",
            Token = token
        };

        IntrospectionResponse result = null;

        var svc = await _Consul.GetService(OrbitServices.IdentityServer);
        result = await TrySendAsync(iRequest, svc);
        if (!result.IsActive && result.IsError)
        {
            svc = await _Consul.GetService(OrbitServices.IdentityServer, true);
            result = await TrySendAsync(iRequest, svc);
        }

        var message = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent(result.Raw, Encoding.UTF8, "application/json")
        };

        return message;

【讨论】:

    猜你喜欢
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 2014-03-06
    • 1970-01-01
    相关资源
    最近更新 更多