4 Replies Latest reply: Feb 22, 2017 7:48 PM by Nate Pluke RSS

    403 Forbidden Session API Failure

    Nate Pluke

      I've been banging my head on this and hoping to get some assistance with getting single sign on working using the Session API.

       

      Essentially it appears that my certificates load successfully but I get an immediate 403 as soon as the call is made with no additional data. I have reviewed the logs on the Qlik server but haven't found anything has helped me yet to determine the problem.

       

      I am using the QlikClient cert in my local store which includes the private keys - I have ensure my asp.net application pool identity has access to the cert.

       

      Below is my code (C#) which I built following the tutorials and code samples here:

       

      ASP.NET Session Tutorial

      https://drive.google.com/file/d/0BxBEVQthCb29b3l1ME1SQXpkZkU/view

       

      IIS Configuration Tutorial

      https://drive.google.com/file/d/0BxBEVQthCb29ek52R2pCZ3ZOX00/view

       

      Code Samples

      http://branch.qlik.com/#!/project/56728f52d1e497241ae69864

       

      I have read and re-read the docs on the forums and support pages but with no luck.

       

      public class QlikAuthenticationService
          {      
              public Result<string> StartQlikSession(QlikUserAccessInformation access, string aspnetSessionID)
              {
                  var result = new Result<string>();
      
      
                  var certificate = LoadQlikCertificate(access.ClientCertificateName);
                  result += certificate;
      
      
                  if (certificate.Success)
                  {
                      try
                      {
                          // ensure handling of self signed certs
                          ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
      
      
                          // establish url (ie https://reports.domain.com:4243/qps/test/session)
                          string url = $"https://{access.ServerDomain}:{access.ServerPort}/qps/{access.VirtualProxyName}/session";
                          string xrfKey = "ZYX_random_string_132456";
      
      
                          string body = $"{{ 'UserId': '{access.UserID}', 'UserDirectory':'{access.UserDirectory}', 'Attributes': [], 'SessionId':'{aspnetSessionID}' }}";
                          byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
      
      
                          HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "?Xrfkey=" + xrfKey);
                          request.ClientCertificates.Add(certificate.Value);
                          request.Method = "POST";
                          request.Accept = "application/json";
                          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();
      
      
                          HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                          Stream stream = response.GetResponseStream();
                          if (stream != null) result.Value = new StreamReader(stream).ReadToEnd();
                      }
                      catch (Exception exc)
                      {
                          result.AddException(exc, this, "Unable to start Qlik session.");
                      }
                  }
      
      
                  return result;
              }
      
      
              public Result<X509Certificate2> LoadQlikCertificate(string certificateName)
              {
                  Result<X509Certificate2> result = new Result<X509Certificate2>();
      
      
                  try
                  {
                      X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                      store.Open(OpenFlags.ReadOnly);
      
      
                      var certificates = store.Certificates.Cast<X509Certificate2>();
      
      
                      if (certificates != null && certificates.Count() > 0)
                      {
                          var certificate = certificates.FirstOrDefault(c => c.FriendlyName == certificateName);
      
      
                          if (certificate != null)
                          {
                              result.Value = certificate;
                          }
                          else
                          {
                              result.AddFailure(Results.Reports.QLIK_ACCESS_FAILURE, "Unable to connect to Qlik Reporting server.", this, $"No {certificateName} certificate found in store");
                          }
                      }
                      else
                      {
                          result.AddFailure(Results.Reports.QLIK_ACCESS_FAILURE, "Unable to connect to Qlik Reporting server.", this, "No certificates found in store");
                      }
                  }
                  catch (Exception exc)
                  {
                      result.AddException(exc, this, "Unable to load Qlik client certificate.");
                  }
      
      
                  return result;
              }
          }
      
      
          public class QlikUserAccessInformation
          {
              public string ServerDomain { get; set; } = "reports.domain.com";
      
      
              public int ServerPort { get; set; } = 4243;
      
      
              public string VirtualProxyName { get; set; } = "test";
      
      
              public string ClientCertificateName { get; set; } = "QlikClient";
      
      
              public string UserDirectory { get; set; } = "QLIK-SENSE";
      
      
              public string UserID { get; set; } = "MyUsername";
          }
      
      

       

      Below is my Qlik Sense Virtual Proxy Configuration:

       

      2017-02-15 13_03_17-Edit virtual proxy - QMC.png

      2017-02-15 13_03_17-Edit virtual proxy - QMC - 2.png

      In the above configuration, I have replaced my actual domain name with "domain.com". The Qlik server is at reports.domain.com and my ASP.NET application is at dev.dashboard.domain.com (which I have mapped to local host using a hosts mapping on my machine). The IPs in the whitelist are my networks public IP address and the servers IP address.

       

      One final note - I have attempted to set this up using PostMan as well, however I am always getting a 403 Forbidden but with this error message: XSRF prevention check failed. Possible XSRF discovered. I am passing the XSRF header/url param in PostMan as well.