我使用IdentityServer4来保护一些webapis。由于我们的客户设置很奇怪,我们需要支持一个设置,我们将有多个运行IdentityServer4的应用程序向不同的客户发出令牌。但是,这些客户最终会打电话给一些共同的服务。
因此,这些公共服务需要能够从IdentityServer4的多个实例验证令牌。由于您在启动时向资源服务器注册了IdentityServer的实例,我认为只要所有IdentityServer以相同的方式签署令牌,它就会起作用。
我认为将IdentityServer设置为使用共享X509证书将允许在配置为使用不同IdentityServer的资源服务器上验证来自一个IdentityServer的令牌,但似乎并非如此。从Server1请求令牌,然后使用Server2将其提交到资源服务器不起作用,即使它们都使用相同的证书。
有没有办法让这项工作?
答案 0 :(得分:0)
您使用的是JWT还是参考代币?
参考令牌由持有权限的身份服务器验证。可能很难使用不同的身份服务器并验证由另一个提供的令牌而不是验证它的令牌。如果您使用的是JWT,则可以使用Discovery-Endpoint捕获公钥。然后你应该能够使用它来验证签名......
您可以这样做:
// Define the client to access the IdentityServer Discovery-Endpoint
var discos = new DiscoveryClient(ConfigurationManager.AppSettings["IdentityserverLocation"]);
var disco = await discos.GetAsync();
// get the public key from the discovery-endpoint
var keys = disco.KeySet.Keys;
//Build the authorization request
//param: Disco.AuthorizeEndpoint --> retrieves the authorization url from the identityserver
var request = new AuthorizeRequest(disco.AuthorizeEndpoint);
var url = request.CreateAuthorizeUrl(
clientId: ConfigurationManager.AppSettings["ClientId"],
responseType: "id_token",
scope: "openid profile email",
responseMode: OidcConstants.ResponseModes.FormPost,
redirectUri: ConfigurationManager.AppSettings["RedirectUrl"],
state: CryptoRandom.CreateUniqueId(),
nonce: CryptoRandom.CreateUniqueId());
//Try to initiate validation
try
{
// Check if the token data exists in the request, parse is to a correct token
var idToken = Request.Form.Get("id_token");
JwtSecurityToken j = new JwtSecurityToken(idToken);
var keylist = new List<SecurityKey>();
foreach (var webKey in disco.KeySet.Keys)
{
var exp = Base64Url.Decode(webKey.E);
var mod = Base64Url.Decode(webKey.N);
var key = new RsaSecurityKey(new RSAParameters() { Modulus = mod, Exponent = exp });
keylist.Add(key);
}
//define the parameters for validation of the token
var parameters = new TokenValidationParameters
{
ValidIssuer = disco.Issuer,
ValidAudience = "viper",
IssuerSigningKeys = keylist,
};
var handler = new JwtSecurityTokenHandler();
handler.InboundClaimTypeMap.Clear();
//validate the token using the defined parameters, return the token when validation is succesful
var user = handler.ValidateToken(j.RawData, parameters, out var validatedtoken);