【问题标题】:QRS API call returns "The client certificate credentials were not recognized"QRS API 调用返回“无法识别客户端证书凭据”
【发布时间】:2018-05-09 15:31:25
【问题描述】:
  1. 使用 QMC 导出的 Qlik Sense 证书(client.pfx、root.cer、server.pfx)。

  2. 使用 MMC 将证书导入 IIS Web 服务器。服务器和客户端证书存储 Personal->Certificates,root 存储受信任的根证书颁发机构。

  3. 使用来自商店的 QlikClient 证书从 ASP.NET 控制器请求 QRS API(代码如下)。尝试了各种用户 ID 和目录,包括 INTERNAL/sa_repository,但在所有情况下都出现错误“发送请求时发生错误。无法识别客户端证书凭据”。

测试端点:https://server:4242/qrs/about

我在网上搜索过,但没有找到我做错了什么,我应该提供什么凭据。

另一方面,当我将导出的证书转换为单独的 .key/.crt 文件(使用 https://www.markbrilman.nl/2011/08/howto-convert-a-pfx-to-a-seperate-key-crt-file/)并在来自 Web 服务器的 Postman 中使用它们时,它可以正常工作,实际上标题中包含任何 UserId (我想在那种情况下它会被忽略)。

ASP.NET 控制器:

    public X509Certificate2 LoadQlikCertificate()
    {
        X509Certificate2 certificate = null;

        try
        {
            // Open certification store (MMC)
            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);

            // Get certiface based on the friendly name
            certificate = store.Certificates.Cast<X509Certificate2>().FirstOrDefault(c => c.FriendlyName == "QlikClient");

            // Logging for debugging purposes
            if (certificate != null)
            {
                logger.Log(LogLevel.Warning, $"Certificate: {certificate.FriendlyName} {certificate.GetSerialNumberString()}");
            }
            else
            {
                logger.Log(LogLevel.Warning, $"Certificate: No certificate");
            }

            // Close certification store
            store.Close();

            // Return certificate
            return certificate;
        }
        catch (Exception e)
        {
            ...
        }
    }


    /* Get Qlik API response
     ***********************/
    [HttpGet("getqlikapi")]
    public IActionResult GetQlikAPI()
    {
        // Get Qlik certificate
        var certificate = this.LoadQlikCertificate();

        try
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

            // Set server name
            string server = "server";
            // HARDCODED USER AND DIRECTORY FOR TESTING
            string userID = "sa_repository";  // tried also other user ids
            string userDirectory = "INTERNAL"; 
            // Set Xrfkey header to prevent cross-site request forgery
            string xrfkey = "abcdefg123456789";

            // Create URL to REST endpoint
            string url = $"https://{server}:4242/qrs/about?xrfkey={xrfkey}";

            // The JSON object containing the UserId and UserDirectory
            string body = $"{{ 'UserId': '{userID}', 'UserDirectory': '{userDirectory}', 'Attributes': [] }}";
            // Encode the json object and get the bytes
            byte[] bodyBytes = Encoding.UTF8.GetBytes(body);

            // Create the HTTP Request                
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            // Add the method to authentication the user
            request.ClientCertificates.Add(certificate);
            // POST request will be used
            request.Method = "POST";
            // The request will accept responses in JSON format
            request.Accept = "application/json";
            // A header is added to validate that this request contains a valid cross-site scripting key (the same key as the one used in the url)
            request.Headers.Add("X-Qlik-Xrfkey", xrfkey);
            request.ContentType = "application/json";
            request.ContentLength = bodyBytes.Length;

            Stream requestStream = request.GetRequestStream();
            requestStream.Write(bodyBytes, 0, bodyBytes.Length);
            requestStream.Close();

            // Make the web request and get response
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream stream = response.GetResponseStream();

            // Return string in response
            //return new OkObjectResult(stream != null ? new StreamReader(stream).ReadToEnd() : string.Empty);
            return new OkObjectResult("test");
        }
        catch (Exception e)
        {
            ...
        }
    }

【问题讨论】:

    标签: asp.net rest api qliksense


    【解决方案1】:

    我在我们正在构建的系统上遇到了这个问题。

    问题是用户没有证书的权限。

    打开证书管理器(开始 > 管理计算机证书) 找到所需的证书。

    右击证书>所有任务>管理私钥>添加>[选择合适的用户]

    注意:管理用户证书没有管理私钥选项。

    【讨论】:

      猜你喜欢
      • 2019-08-25
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      • 2015-04-18
      • 1970-01-01
      • 2022-06-25
      • 2022-08-19
      • 1970-01-01
      相关资源
      最近更新 更多