无法使用DiscoveryClient,提示"Issuer name does not match authority"。

22

使用IdentityModel的DiscoveryClient进行GET时,我遇到以下错误:

var discoveryResponse = await DiscoveryClient.GetAsync("https://localhost/IdentityServer");

颁发者名称与认证机构不匹配:https://localhost/identityserver

目标URL是在启用IdentityServer4的IIS上运行的ASP.NET Core Web应用程序。客户端应用程序是在同一台计算机上运行的经典ASP.NET Web应用程序。

显然,根据discoveryResponse.Raw的内容可以看出,GET确实能够从IdentityServer中检索到值:

{
  "issuer": "https://localhost/identityserver",
  "jwks_uri": "https://localhost/IdentityServer/.well-known/openid-configuration/jwks",
  "authorization_endpoint": "https://localhost/IdentityServer/connect/authorize",
  "token_endpoint": "https://localhost/IdentityServer/connect/token",
  "userinfo_endpoint": "https://localhost/IdentityServer/connect/userinfo",
  "end_session_endpoint": "https://localhost/IdentityServer/connect/endsession",
  "check_session_iframe": "https://localhost/IdentityServer/connect/checksession",
  "revocation_endpoint": "https://localhost/IdentityServer/connect/revocation",
  "introspection_endpoint": "https://localhost/IdentityServer/connect/introspect",
  "frontchannel_logout_supported": true,
  "frontchannel_logout_session_supported": true,
  "scopes_supported": [ "CustomIdentityResources", "profile", "openid", "MyAPI.full_access", "offline_access" ],
  "claims_supported": [],
  "grant_types_supported": [ "authorization_code", "client_credentials", "refresh_token", "implicit" ],
  "response_types_supported": [ "code", "token", "id_token", "id_token token", "code id_token", "code token", "code id_token token" ],
  "response_modes_supported": [ "form_post", "query", "fragment" ],
  "token_endpoint_auth_methods_supported": [ "client_secret_basic", "client_secret_post" ],
  "subject_types_supported": [ "public" ],
  "id_token_signing_alg_values_supported": [ "RS256" ],
  "code_challenge_methods_supported": [ "plain", "S256" ]
}
4个回答

31

有趣。我在追踪issuer字段的来源时遇到了麻烦。这是从托管应用程序的上下文中派生出来的吗?例如,如果我在名为“IdentityProvider”的应用程序中在IIS中托管IdenityServer端点,则发行者将是https://localhost/identityprovider(小写)? - Sigurd Garshol
1
如果我没记错,发行人名称始终是小写的(为了避免出现这些问题)。 - leastprivilege
使用小写字母确实解决了问题。谢谢! - Sigurd Garshol
1
@SigurdGarshol,你能分享一下你是如何在IS4中使用https端点的吗?我无法让RequestClientCredentialsAsynchttps一起工作。 - Ruskin
@Ruskin:不知道你遇到了什么样的错误,很难回答。如果问题是“你是如何启用https的”,那么我们做的就是:告诉WebHostBuilder使用带有Https的Kestrel,并提供从文件中读取的自签名证书。这仅适用于将IS4端点作为控制台主机运行时 - 在“正式”的IIS下运行时,我们将https和证书留给Web服务器。 - Sigurd Garshol

20
在无法更改服务器代码以适应策略的情况下,您可以更改策略设置以允许名称不匹配。例如,我正在尝试在Azure Rest API上使用DiscoveryClient,而issuer是https://sts.windows.net/{{tenant_id}},而所有端点都以https://login.microsoft.com/{{tenant_id}}开头。只需将ValidateIssuerName和ValidateEndpoints字段设置为false即可。
var tenant_id = "8481D2AC-893F-4454-8A3B-A0297D301278"; // Made up for this example
var authority = $"https://login.microsoftonline.com/{tenant_id}";
DiscoveryClient discoveryClient = new DiscoveryClient(authority);

// Accept the configuration even if the issuer and endpoints don't match
discoveryClient.Policy.ValidateIssuerName = false;
discoveryClient.Policy.ValidateEndpoints = false;

var discoResponse = await discoveryClient.GetAsync();

后续编辑

自发布此消息以来,DiscoveryClient类已被弃用。

以下是新的调用语法:

var client = new HttpClient();
var discoResponse = await client.GetDiscoveryDocumentAsync(
    new DiscoveryDocumentRequest
    {
        Address = authority,
        Policy =
        {
            ValidateIssuerName = false,
            ValidateEndpoints = false,
        },
    }
);

1
这解决了我的问题。非常感谢!在我的情况下,我们使用外部 https URL 作为发行者,使用内部 http URL 作为授权机构。 - devC

2

其他答案解决了客户端问题 - 使其接受小写的发行人。

这会改变发现文档中发行人的大小写:

默认情况下,Identity Server似乎会将发行人Uri更改为小写。这会导致发现文档中发行人的小写;以及您在代码/发布中键入的其他所有内容的大小写。

我在我的Identity Server应用程序中通过Startup,ConfigureServices方法修复了这个问题。

            var builder = services.AddIdentityServer(options => { options.LowerCaseIssuerUri = false; })

使用这种方式意味着发行者在发现文档中的情况与所有其他URI的情况相同。

0

如果发现请求Discovery Client的URL(或者在我的情况下,用于验证期间访问令牌内省的URL)包含转义空格(即"%20"而不是" "),也会出现此错误。如果在Identity Server中精确比较URL,则这种情况有点合理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接