c# - AddOpenIdConnect 与手动配置 - SecurityTokenSignatureKeyNotFoundException
问题描述
现有系统
我们正在使用 Identity Server 4 为 Google、Azure 或其他外部提供商提供单点登录功能,没有任何问题。我们所要做的就是添加客户详细信息和授权网址或迪斯科网址(例如.well-known/openid-configuration
),一切都按预期工作。
设想
我们的一位外部身份提供者表示,他们无法提供公共发现文档 url,他们仅在内部将其设为私有。然后他们作为 Json 文件提供(其中包含该 url 提供的确切 json 文本)。因此,我们尝试使用该 json 文件中的值来手动设置所有这些端点 url 和AddOpenIdConnect
设置OpenIdConnectConfiguration
。
它正确地重定向到授权请求的外部提供者,我们可以在外部系统中登录。但是当请求返回到我们的 Idsrv4 时,它无法验证id_token
. 我们得到SecurityTokenSignatureKeyNotFoundException
. 我们确实尝试设置JwksUri
但是,仍然没有运气。
我设法通过使用 Demo Identity 服务器复制了相同的行为,请参阅以下内容:
.AddOpenIdConnect("manualidsrv", "IdentityServer Manual", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.Authority = "https://demo.identityserver.io/";
options.ClientId = "login";
options.ResponseType = "id_token";
options.SaveTokens = true;
options.Configuration = new OpenIdConnectConfiguration
{
Issuer = "https://demo.identityserver.io",
JwksUri = "https://demo.identityserver.io/.well-known/openid-configuration/jwks",
AuthorizationEndpoint = "https://demo.identityserver.io/connect/authorize",
TokenEndpoint = "https://demo.identityserver.io/connect/token",
UserInfoEndpoint = "https://demo.identityserver.io/connect/userinfo",
EndSessionEndpoint = "https://demo.identityserver.io/connect/endsession",
ResponseTypesSupported =
{
"code",
"token",
"id_token",
"id_token token",
"code id_token",
"code token",
"code id_token token"
},
GrantTypesSupported = {
"authorization_code",
"client_credentials",
"refresh_token",
"implicit",
"password",
"urn:ietf:params:oauth:grant-type:device_code"
},
ResponseModesSupported =
{
"form_post",
"query",
"fragment"
},
IdTokenSigningAlgValuesSupported = { "RS256" },
};
我们得到的错误是
SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match keys:
kid: '3BA75FA392E4DAFAC2737B5B4644AA85',
token: '{"alg":"RS256","kid":"3BA75FA392E4DAFAC2737B5B4644AA85","typ":"JWT"}.{"nbf":1596656241,"exp":1596656541,"iss":"https://demo.identityserver.io","aud":"login","nonce":"637322530390217907.xxx","iat":1596656241,"s_hash":"exiANrEFoXVDwA5BK1mGTg","sid":"D90FD8D4FA73AD590E3C53155375EA49","sub":"1","auth_time":1596652196,"idp":"local","name":"Alice Smith","given_name":"Alice","family_name":"Smith","email":"AliceSmith@email.com","email_verified":true,"website":"http://alice.com","amr":["pwd"]}'.
我试图检查 jwksUri:https ://demo.identityserver.io/.well-known/openid-configuration/jwks ,我可以在那里看到正确的孩子 '3BA75FA392E4DAFAC2737B5B4644AA85'。
因此,在我看来,如果我们手动设置配置,Idsrv4 就无法正确加载这些密钥。
有一些建议通过使用ConfigurationManager
如下手动加载 SigningKeys:
new ConfigurationManager<OpenIdConnectConfiguration>($"DiscoveryEndpointUrl", new OpenIdConnectConfigurationRetriever());
但是,由于我们无权访问该端点 url,因此它对我们不起作用。
无论如何强制 Idsrv 从 jwksUri 加载密钥或手动提供密钥?
您能否建议解决此签名密钥异常?
解决方案
一种解决方法可能是将来自提供者的发现文档放在 JSON 文档中,然后将其作为静态资源包含在您的 IdentityServer 中?然后只需在配置中添加指向该静态端点的链接?
我怀疑 IdentityServer 是否关心该文档是否在本地托管。
推荐阅读
- python - pytest monkeypatch 终端大小
- c# - 如何编写没有根元素的碎片化 xml 文件?
- wordpress - WordPress + ngrok 的问题,我使用 WAMPServer
- ios - Swift - 什么是 SCNCamera 的定义和用途
- python - "是什么意思
's'>" 是什么意思? - javascript - 如何使用 R 抓取由 js/ajax 技术生成的网站数据?
- macos - 使用 Electron-Builder 构建后运行 .dmg 应用程序会导致“应用程序意外退出”。
- powerbi - PowerBI:当满足任一 VAR 时返回计算
- php - 在 Wordpress 中调用动态数据
- javascript - 这段代码如何找到两个对象数组之间的差异?