Identity Server 4发出JWT验证失败

Identity Server 4发出JWT验证失败,jwt,identityserver4,identityserver3,owin-middleware,Jwt,Identityserver4,Identityserver3,Owin Middleware,我有一个基于Identity Server 4.Net Core v2运行的Identity Server,目标是完整的.Net framework,我有一个基于ASP.Net Web API 2(即非.Net Core)构建的ASP.Net WebAPI,它使用Identity Server 3 OWIN中间件进行令牌身份验证 在本地运行时,一切正常-我可以使用Postman使用RO密码流从Identity Server请求访问令牌,然后我可以向WebAPI发出请求,将令牌作为承载令牌发送-一

我有一个基于Identity Server 4.Net Core v2运行的Identity Server,目标是完整的.Net framework,我有一个基于ASP.Net Web API 2(即非.Net Core)构建的ASP.Net WebAPI,它使用Identity Server 3 OWIN中间件进行令牌身份验证

在本地运行时,一切正常-我可以使用Postman使用RO密码流从Identity Server请求访问令牌,然后我可以向WebAPI发出请求,将令牌作为承载令牌发送-一切正常

现在,当所有东西都托管在我们的测试服务器上时,我在调用WebAPI时遇到了一个问题——我只是得到了一个未经授权的响应。使用检查从Identity server返回的令牌是否正常,但WebAPI中JWT的验证失败。 在进一步的调查中,在添加Katana日志之后,我看到报告了SecurityTokenInvalidAudienceException

观众验证失败。观众: “,XXXWebApi”。不匹配: validationParameters.ValidAudience: 或validationParameters.Validudiences:'null'

看看JWT的观众,我们有:

aud:,XXXWebApi

在WebAPI启动中,我调用

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = , // path to our local ID Server
            ClientId = "XXXWebApi",
            ClientSecret = "XXX_xxx-xxx-xxx-xxx",
            RequiredScopes = new[] { "XXXWebApi" }
        });
因此,JWT受众看起来不错,但显然与从IdP发现端点构建的中间件所提供的内容不匹配。我本以为这是因为我指定了所需的作用域以包括XXXWebApi,这足以匹配JWTs受众,但似乎被忽略了

我不确定如何更改WebAPI身份验证选项以使其正常工作

编辑:我将WebAPI令牌身份验证选项更改为使用验证端点,这在IdentityServer中也会失败,并出现相同的错误。
但是,如果我使用相同的令牌直接从Postman调用Identity Server内省端点,它会成功。

据我所知,您的WebAPI项目被用作API资源

如果是,请从UseIdentityServerBearerTokenAuthentication中删除“clientId”和“clientSecret”,保留“RequiredScopes”和您可能还需要设置ValidationMode=ValidationMode


当您使用引用令牌时,您需要它们。根据您所说的,您正在使用JWT。检查,然后。

据我所知,您的WebAPI项目被用作API资源

如果是,请从UseIdentityServerBearerTokenAuthentication中删除“clientId”和“clientSecret”,保留“RequiredScopes”和您可能还需要设置ValidationMode=ValidationMode


当您使用引用令牌时,您需要它们。根据您所说的,您正在使用JWT。检查,然后。

好的,所以在做了大量的挠头和尝试各种事情之后,我至少有了一些工作

我必须确保Identity Server是根据公开可用的DNS托管的,并在IdentityServerBealerTokenAuthenticationOptions中配置Authority值以使用相同的值

这样,发布的任何令牌在JWT受众aud中都具有xx.yy.zz完整域名,当WebAPI中的OWIN验证中间件验证JWT时,它使用相同的地址进行比较,而不是本地主机


我仍然有点困惑,为什么中间件不能只使用作用域值进行验证,因为令牌是与API资源作用域XXXWebAPi一起在访问群体中发布的,并且API在选项中请求相同的作用域id/名称,如图所示。

好,所以,在做了很多努力和尝试之后,我至少有了一些工作

我必须确保Identity Server是根据公开可用的DNS托管的,并在IdentityServerBealerTokenAuthenticationOptions中配置Authority值以使用相同的值

这样,发布的任何令牌在JWT受众aud中都具有xx.yy.zz完整域名,当WebAPI中的OWIN验证中间件验证JWT时,它使用相同的地址进行比较,而不是本地主机


我仍然有点困惑,为什么中间件不能只使用作用域值进行验证,因为令牌是与API资源作用域XXXWebAPi一起在访问群体中发布的,并且API在所示的选项中请求相同的作用域id/名称。

您是否确认这两个位置的代码完全相同?你检查过网址了吗?它们一切正常吗?是的,我直接从VStudio发布代码,部署到服务器,只需更改配置文件中的URL,以确保它们指向Identity server的正确端口。如果我从postman单独调用令牌内省端点,那么令牌验证很好。问题在于IdentityServer OWIN中间件中令牌的自动验证,但我不知道如何修复它。您是否使用IdSrv3验证从IdSrv4获得的JWT?服务器是Identity server 4,并且
我在WebAPI中使用IdentityServer3.AccessTokenValidation,它是由IdServer团队创建的中间件。所以它不完全是IdentityServer 3,它只是OWIN中间件,所以它应该与所使用的目标Identity Server版本无关。@MarkBennetts您最终解决了这个问题吗?我正在努力解决这个问题,但还找不到任何解决方案。您是否确认这两个地方的代码完全相同?你检查过网址了吗?它们一切正常吗?是的,我直接从VStudio发布代码,部署到服务器,只需更改配置文件中的URL,以确保它们指向Identity server的正确端口。如果我从postman单独调用令牌内省端点,那么令牌验证很好。问题在于IdentityServer OWIN中间件中令牌的自动验证,但我不知道如何修复它。您是否使用IdSrv3验证从IdSrv4获得的JWT?服务器是Identity server 4,我在WebAPI中使用IdentityServer3.AccessTokenValidation,这是IdServer团队创建的中间件。所以它不完全是IdentityServer 3,它只是OWIN中间件,所以它应该与所使用的目标Identity Server版本无关。@MarkBennetts您最终解决了这个问题吗?我也在努力解决这个问题,但还找不到任何解决方案。好吧,我今天不在办公室,所以我会尝试删除ClientID和Secret,尽管我不明白为什么这会对JWT验证产生影响。验证模式默认为,我将其更改为Local,以确保在尝试进行IDP验证但未通过验证的情况下执行本地验证,所以我也会将其还原。好吧,因为我怀疑这没有什么区别-在JWT的本地验证期间没有使用ClientID和Secret,所以我是否提供它们也没有区别。好的,我今天不在办公室,所以我将尝试删除ClientID和Secret,尽管我不明白为什么这会对JWT验证产生影响。验证模式默认为,我将其更改为Local,以确保在尝试IDP验证但未通过验证的情况下执行本地验证,因此我也会将其还原。好的,因为我怀疑这没有什么区别-在JWT的本地验证期间没有使用ClientID和Secret,所以我是否提供它们也没有区别。您可以设置相关的tokenvalidationparameters中的委托和按需自定义默认值是它同时检查。您可以在tokenvalidationparameters中设置相关委托并按需自定义默认值是它同时检查这两个。