如果早期的中间件已经这样做,如何告诉IdentityServer 4中间件不要进行身份验证?

时间:2016-12-12 16:02:34

标签: asp.net-core asp.net-core-mvc asp.net-core-webapi asp.net-core-middleware asp.net-core-identity

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

JWT

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
});

Identity Server 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中间件不要进行身份验证呢?

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

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

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

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

但是我得到了范围验证失败:

Scope validation failed. Return 403.

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

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

感谢您的帮助!

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

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

谢谢!

0 个答案:

没有答案