1

我的 ASP.NET Core REST API 使用 2 个身份验证中间件 - JWT 来验证用户(由 ADFS 颁发的令牌),以及 IdentityServer 来验证来自其他服务的调用。这些中间件的配置如下所示:

智威汤逊

var tokenValidationParameters = new TokenValidationParameters
{
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = new X509SecurityKey(federationMetadata.GetSigningCertificate()),
    ValidateIssuer = true,
    ValidIssuer = federationMetadata.GetIssuerUri().AbsoluteUri,
    ValidateAudience = true,
    ValidAudience = validAudience,
    ValidateLifetime = true,
    ClockSkew = TimeSpan.Zero
};

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    TokenValidationParameters = tokenValidationParameters
});

身份服务器 4 (IDS)

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
    Authority = dbConfig.IdentityServer.AbsoluteUri,
    ScopeName = Configuration.ServiceName,
    RequireHttpsMetadata = false
}

我在使用此设置时遇到问题:

当用户从 ADFS 传递令牌时,JWT 中间件会成功验证令牌。然后 IDS 中间件无法验证令牌并引发错误:

IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.RsaSecurityKey , KeyId: <MyRsaKey>

这是意料之中的。如果较早的中间件已成功验证请求,我如何告诉 IDS 中间件不进行验证?

我已经尝试了几件事。在我看来,理想的做法是解决OnMessageReceived用户已通过身份验证的 IDS 事件,并告诉 IDS 中间件不要做进一步检查:

JwtBearerEvents = new JwtBearerEvents()
{
    OnMessageReceived = async (context) =>
    {
        if(UserIsAlreadyAuthenticated)
            DoNothingMore();
    }
}   
  • 我如何测试用户是否经过身份验证?
  • 如何告诉中间件接受身份验证并且不再进行处理?

我尝试过捕获 IDSOnAuthenticationFailed事件并跳过中间件:

OnAuthenticationFailed = async (context) =>
{
    if (context.Exception is IdentityServerNotAvailableException)
    {
        context.SkipToNextMiddleware();
    }
}

但然后我得到一个范围验证失败:

Scope validation failed. Return 403.

范围验证在哪里进行?因为似乎 IDS 中间件中的任何错误都会导致范围验证错误,无论我是否SkipToNextMiddleware

如果我删除 IDS 中间件,一切正常。

谢谢你的帮助!

编辑:我现在已经解决了范围验证问题。我尝试ValidateScope = false在 IDS 中间件上设置选项,但这会导致中间件内部出现空引用异常;但我发现如果我注释掉该ScopeName = Configuration.ServiceName选项,范围验证问题就解决了(我在自定义处理程序中处理它 - 不理想)。

仍然需要知道:如果令牌已成功通过身份验证,如何告诉 IdentityServer 中间件跳过,或者在OnMessageReceived事件中识别成功的先前身份验证,以便我可以自己调用SkipToNextMiddleware()那里。

谢谢!

4

0 回答 0