Qlik Community

Qlik Sense Integration, Extensions, & APIs

Discussion board where members can learn more about Integration, Extensions and API’s for Qlik Sense.

switchdevops
New Contributor II

403 Forbidden Session API Failure

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.

Tags (2)
1 Solution

Accepted Solutions
akl
Honored Contributor

Re: 403 Forbidden Session API Failure

Hey Nate,

"The only characters that are allowed for use in the Xrfkey parameter are 0 - 9, a - z, and A - Z."

Using Xrfkey headers ‒ Qlik Sense

Try dropping the _ in your xrf key

4 Replies
switchdevops
New Contributor II

Re: 403 Forbidden Session API Failure

No one has any thoughts on this? Any help would be appreciated.

Thanks!

akl
Honored Contributor

Re: 403 Forbidden Session API Failure

Hey Nate,

"The only characters that are allowed for use in the Xrfkey parameter are 0 - 9, a - z, and A - Z."

Using Xrfkey headers ‒ Qlik Sense

Try dropping the _ in your xrf key

switchdevops
New Contributor II

Re: 403 Forbidden Session API Failure

Thanks - will give this a try.

switchdevops
New Contributor II

Re: 403 Forbidden Session API Failure

That did the trick. Sessions are working now for me. Thanks!

Of course the placeholder value I had in there while I was just trying to get the basics to work was the thing causing it not to. I hadn't seen that article and was just putting in something random figuring pretty much anything was acceptable as long as they matched.

For anyone curious, I did also need to add in this line after the cert validation callback to get it to work fully:


ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls