【问题标题】:Validate token using different server?使用不同的服务器验证令牌?
【发布时间】:2017-07-04 11:17:40
【问题描述】:

我正在使用 IdentityServer4 来保护一些 webapi。由于我们客户设置中的一个怪癖,我们需要支持一个设置,我们将有多个运行 IdentityServer4 的应用程序来向不同的客户端颁发令牌。然而,这些客户端最终会调用一些公共服务。

因此,这些通用服务需要能够验证来自多个 IdentityServer4 实例的令牌。由于您在启动时向资源服务器注册了一个 IdentityServer 实例,我认为只要所有 IdentityServer 以相同的方式签署令牌,它就可以工作。

我假设将 IdentityServer 设置为使用共享 X509 证书将允许来自一个 IdentityServer 的令牌在配置为使用不同 IdentityServer 的资源服务器上进行验证,但情况似乎并非如此。从 Server1 请求令牌,然后使用 Server2 将其提交到资源服务器不起作用,即使它们都使用相同的证书。

有没有办法让这个工作?

【问题讨论】:

  • 在配置资源服务器以使用 Identity Server 进行身份验证时,您需要指定范围和权限等内容...您的所有身份服务器是否都具有与 URI 中相同的“权限”。
  • 很想看到这个问题的答案...有类似的情况,但使用指向同一个身份服务器实例的两个域名 - 这也不起作用,因为您必须设置 Api 资源“权限”到单个 URI。

标签: c# asp.net-core identityserver4


【解决方案1】:

您使用的是 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);

【讨论】:

    猜你喜欢
    • 2015-03-03
    • 1970-01-01
    • 2023-01-12
    • 2021-04-26
    • 2020-07-31
    • 1970-01-01
    • 2019-02-16
    • 2013-04-22
    • 2020-10-08
    相关资源
    最近更新 更多