【问题标题】:Handle error if identityserver discovery document is unreachable如果身份服务器发现文档无法访问,则处理错误
【发布时间】:2021-06-01 04:23:28
【问题描述】:

我有一个使用两种身份验证方案的 .NET 核心 WebAPI,第一个是 AAD,第二个是 identityserver4

    services.AddAuthentication(authOptions =>
    {
        authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        authOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer()//configured below for id4
    .AddAzureADBearer(options => Configuration.Bind("AzureAd", options)); 
    //AAD options
    services.Configure<JwtBearerOptions>(
        AzureADDefaults.JwtBearerAuthenticationScheme, options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
            };
        });

    //id4 options
    services.Configure<JwtBearerOptions>(
        JwtBearerDefaults.AuthenticationScheme, options =>
        {

            options.Authority = "https://****/identity";
            options.Audience = Constants.Audience;
            options.MetadataAddress = "https://****/identity/.well-known/openid-configuration";

            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
            };
        });


    services.AddAuthorization(options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme,AzureADDefaults.BearerAuthenticationScheme) //added both
            .Build();
    });

我目前在我的 startup.cs 中使用此配置,当 identityserver4 主机关闭时,我无法授权 Azure Active Directory 发出的令牌(整个令牌验证失败)&这是我在日志中看到的

System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://****/identity/.well-known/openid-configuration'.
 ---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://****/identity/.well-known/openid-configuration'.
 ---> System.Net.Http.HttpRequestException: nodename nor servname provided, or not known
 ---> System.Net.Sockets.SocketException (0xFFFDFFFF): nodename nor servname provided, or not known
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)

如何处理此类异常,我看到一个问题here,但我认为会有解决方法。

【问题讨论】:

    标签: c# asp.net-core azure-active-directory identityserver4


    【解决方案1】:

    首先,AddJWtBearer,如果在第一个令牌到达时无法到达发现端点,则会抱怨。我在我的系统中实现的一个选项是添加一个中间件,该中间件阻止传入的请求到达它,直到它可以确保 IdentityServer 是可访问的。实现起来并不难。

    它可能看起来像这样:

    如果 AddJwtBearer(通过 ConfigurationManager)之后无法到达发现端点,它将重用现有配置。默认情况下,它将每 24 小时刷新一次。如果失败,则重试周期为 30 秒。

    或者,如果该中间件无法访问 IdentitySerer,则可以直接从请求中“删除”不记名令牌。这样请求就不会触发 AddJwtBearer。

    或者,您可以从 GitHub 下载 AddJwtBearer 的源代码,然后手动修补身份验证方法。..

    【讨论】:

    • 所以根据您的评论,即使令牌是由 AAD 颁发的并且如果 ID4 端点关闭,AddJwtBearer 中间件仍将搜索 ID4 发现文档,唯一的方法是添加中间件如果请求已关闭,则跳过(?)通过 ID4 的请求
    • 我只有使用一个 JwtBearer 处理程序的经验,我想要在我的设置中做的是等待 IdentityServer 可用(比如当我们进行初始部署时 API 可能在 IdentityServer 之前启动)。所以就我而言,我想等待并回复 503 状态码,直到 API 准备好接受流量。就像实时与就绪检查一样。
    • 在内部降低复杂性的另一种方法是在内部仅支持一个令牌并通过 IdentityServer 检索和接受 Azure AD 令牌。所以你的系统只依赖于 IdentityServer。
    • 唯一的问题是,我正在将 AAD 用于主要帐户,并且我正在尝试集成使用 ID4(不是我的实例)的第 3 方 SSO。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多