QRS API调用返回“无法识别客户端证书凭据”

时间:2018-05-09 15:31:26

标签: asp.net rest api qliksense

  1. 使用QMC导出Qlik Sense证书(client.pfx,root.cer,server.pfx)。

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

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

  4. 测试终点: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 in标题(我想在那种情况下它会被忽略)。

    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)
            {
                ...
            }
        }
    

1 个答案:

答案 0 :(得分:0)

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

问题是用户无权使用证书。

打开证书管理器,找到所需的证书。

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