<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Unauthorized 401 error calling QRS APIs in .NET ( no default credentials ) in Integration, Extension &amp; APIs</title>
    <link>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2487675#M21393</link>
    <description>&lt;P&gt;Hi, I have a .NET web app from which I want to call the Qlik Sense QRS APIs: let's take the call to &lt;CODE&gt;/qrs/about&lt;/CODE&gt; as an example. The calls are managed through this Client and the &lt;CODE&gt;GetWebRequest&lt;/CODE&gt; method inside it:&lt;/P&gt;
&lt;LI-CODE lang="csharp"&gt;public class CookieAwareWebClient : WebClient, ICookieAwareWebClient {
    private TimeSpan _timeout;
    private CookieContainer _cookieContainer;
    private QSIdentityCredentials _networkCredentials;

    public CookieAwareWebClient(TimeSpan timeout, ICredentials networkCredential) {
        _cookieContainer = new CookieContainer();
        _timeout = timeout;
        UseDefaultCredentials = networkCredential == null;
        if (!UseDefaultCredentials)
            Credentials = networkCredential;
        //_networkCredentials = new QSIdentityCredentials() { Username = ((NetworkCredential)networkCredential).UserName, Password = ((NetworkCredential)networkCredential).Password };
        Encoding = Encoding.UTF8;

        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    }

    protected override WebRequest GetWebRequest(Uri address)
    {

        var request = (HttpWebRequest)base.GetWebRequest(address);
        if (request == null)
            throw new NullReferenceException("request");

        request.CookieContainer = _cookieContainer;
        request.Timeout = (int)_timeout.TotalMilliseconds;
        request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.BypassCache);

        SetCredentials(ref request, new QSIdentityCredentials() { Username = ((NetworkCredential)Credentials).UserName, Password = ((NetworkCredential)Credentials).Password });

        return request;
    }&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The authentication part is handled through the &lt;CODE&gt;SetCredentials&lt;/CODE&gt; method:&lt;/P&gt;
&lt;LI-CODE lang="csharp"&gt;public static void SetCredentials(ref HttpWebRequest request, QSIdentityCredentials credentials) {
    if (credentials == null) {
        request.UseDefaultCredentials = true;
        return;
    }

    request.UseDefaultCredentials = false;

    if (!credentials.Username.Contains("\\")) {
        var hdCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials.Username + ":" + credentials.Password));
        request.Headers.Add("Authorization", "Basic " + hdCredentials);
        request.Credentials = new NetworkCredential(credentials.Username, credentials.Password);
        return;
    }

    var hdCredentials2 = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials.Username.Split('\\')[1] + ":" + credentials.Password));
    request.Headers.Add("Authorization", "Basic " + hdCredentials2);
    var domain = credentials.Username.Split('\\').First();
    var username = credentials.Username.Split('\\').Last();
    request.Credentials = new NetworkCredential(username, credentials.Password, domain);
    
}&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;When I do not pass credentials to the method and thus use &lt;CODE&gt;useDefaultCredentials = true&lt;/CODE&gt;, the calls succeed because the IIS user is used correctly. However, when I try to use another user so setting useDefaultCredentials = false (which has the &lt;CODE&gt;rootAdmin&lt;/CODE&gt; role in Qlik Sense), the calls always return a 401 unauthorized error. What am I doing wrong?&lt;/P&gt;</description>
    <pubDate>Thu, 17 Oct 2024 14:21:49 GMT</pubDate>
    <dc:creator>alessandrovernile</dc:creator>
    <dc:date>2024-10-17T14:21:49Z</dc:date>
    <item>
      <title>Unauthorized 401 error calling QRS APIs in .NET ( no default credentials )</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2487675#M21393</link>
      <description>&lt;P&gt;Hi, I have a .NET web app from which I want to call the Qlik Sense QRS APIs: let's take the call to &lt;CODE&gt;/qrs/about&lt;/CODE&gt; as an example. The calls are managed through this Client and the &lt;CODE&gt;GetWebRequest&lt;/CODE&gt; method inside it:&lt;/P&gt;
&lt;LI-CODE lang="csharp"&gt;public class CookieAwareWebClient : WebClient, ICookieAwareWebClient {
    private TimeSpan _timeout;
    private CookieContainer _cookieContainer;
    private QSIdentityCredentials _networkCredentials;

    public CookieAwareWebClient(TimeSpan timeout, ICredentials networkCredential) {
        _cookieContainer = new CookieContainer();
        _timeout = timeout;
        UseDefaultCredentials = networkCredential == null;
        if (!UseDefaultCredentials)
            Credentials = networkCredential;
        //_networkCredentials = new QSIdentityCredentials() { Username = ((NetworkCredential)networkCredential).UserName, Password = ((NetworkCredential)networkCredential).Password };
        Encoding = Encoding.UTF8;

        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    }

    protected override WebRequest GetWebRequest(Uri address)
    {

        var request = (HttpWebRequest)base.GetWebRequest(address);
        if (request == null)
            throw new NullReferenceException("request");

        request.CookieContainer = _cookieContainer;
        request.Timeout = (int)_timeout.TotalMilliseconds;
        request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.BypassCache);

        SetCredentials(ref request, new QSIdentityCredentials() { Username = ((NetworkCredential)Credentials).UserName, Password = ((NetworkCredential)Credentials).Password });

        return request;
    }&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The authentication part is handled through the &lt;CODE&gt;SetCredentials&lt;/CODE&gt; method:&lt;/P&gt;
&lt;LI-CODE lang="csharp"&gt;public static void SetCredentials(ref HttpWebRequest request, QSIdentityCredentials credentials) {
    if (credentials == null) {
        request.UseDefaultCredentials = true;
        return;
    }

    request.UseDefaultCredentials = false;

    if (!credentials.Username.Contains("\\")) {
        var hdCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials.Username + ":" + credentials.Password));
        request.Headers.Add("Authorization", "Basic " + hdCredentials);
        request.Credentials = new NetworkCredential(credentials.Username, credentials.Password);
        return;
    }

    var hdCredentials2 = Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials.Username.Split('\\')[1] + ":" + credentials.Password));
    request.Headers.Add("Authorization", "Basic " + hdCredentials2);
    var domain = credentials.Username.Split('\\').First();
    var username = credentials.Username.Split('\\').Last();
    request.Credentials = new NetworkCredential(username, credentials.Password, domain);
    
}&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;When I do not pass credentials to the method and thus use &lt;CODE&gt;useDefaultCredentials = true&lt;/CODE&gt;, the calls succeed because the IIS user is used correctly. However, when I try to use another user so setting useDefaultCredentials = false (which has the &lt;CODE&gt;rootAdmin&lt;/CODE&gt; role in Qlik Sense), the calls always return a 401 unauthorized error. What am I doing wrong?&lt;/P&gt;</description>
      <pubDate>Thu, 17 Oct 2024 14:21:49 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2487675#M21393</guid>
      <dc:creator>alessandrovernile</dc:creator>
      <dc:date>2024-10-17T14:21:49Z</dc:date>
    </item>
    <item>
      <title>Re: Unauthorized 401 error calling QRS APIs in .NET ( no default credentials )</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2487819#M21396</link>
      <description>&lt;P&gt;Getting that flow to work can be rather tricky. It's easy to get something wrong when trying to set up all the headers and credentials and everything. I have this library for doing this type of connections that might be of interest to you:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://www.nuget.org/packages/QlikSenseRestClient/" target="_blank"&gt;https://www.nuget.org/packages/QlikSenseRestClient/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;With that library you can set up your connection like this:&lt;/P&gt;
&lt;PRE&gt;var restClient = new RestClient(url);&lt;BR /&gt;restClient.AsNtlmUserViaProxy(new NetworkCredential(username, password));&lt;BR /&gt;var rsp = restClient.Get&amp;lt;JToken&amp;gt;("/qrs/about");&lt;/PRE&gt;
&lt;P&gt;If you want to look at how the credential part is set up in that library, then this part is probably the most relevant:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://github.com/kolsrud/qlik_rest_sdk/blob/master/Qlik.Sense.RestClient/Qlik.Sense.RestClient/RestClient.cs#L207" target="_blank"&gt;https://github.com/kolsrud/qlik_rest_sdk/blob/master/Qlik.Sense.RestClient/Qlik.Sense.RestClient/RestClient.cs#L207&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 18 Oct 2024 06:50:12 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2487819#M21396</guid>
      <dc:creator>Øystein_Kolsrud</dc:creator>
      <dc:date>2024-10-18T06:50:12Z</dc:date>
    </item>
    <item>
      <title>Re: Unauthorized 401 error calling QRS APIs in .NET ( no default credentials )</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2487836#M21397</link>
      <description>&lt;P&gt;Seems good, but my project is old and uses .net framework 4.5. I can't import that&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 18 Oct 2024 08:03:08 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2487836#M21397</guid>
      <dc:creator>alessandrovernile</dc:creator>
      <dc:date>2024-10-18T08:03:08Z</dc:date>
    </item>
    <item>
      <title>Re: Unauthorized 401 error calling QRS APIs in .NET ( no default credentials )</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2490529#M21451</link>
      <description>&lt;P&gt;I resolved in this way:&lt;/P&gt;
&lt;LI-CODE lang="csharp"&gt;public static void SetCredentials(ref HttpWebRequest request, NetworkCredential credentials) {
    if (credentials == null) {
        request.UseDefaultCredentials = true;
        return;
    }

    request.UseDefaultCredentials = false;

    var credentialCache = new CredentialCache();


    if (credentials.UserName.Contains("\\"))
    {
        credentials.Domain = credentials.UserName.Split('\\').First();
        credentials.UserName = credentials.UserName.Split('\\').Last();
    }

    
    credentialCache.Add(new Uri($"{request.Address.Scheme}://{request.Host}"), "ntlm", credentials);
    request.Credentials = credentialCache;

}&lt;/LI-CODE&gt;</description>
      <pubDate>Mon, 04 Nov 2024 08:59:38 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/Unauthorized-401-error-calling-QRS-APIs-in-NET-no-default/m-p/2490529#M21451</guid>
      <dc:creator>alessandrovernile</dc:creator>
      <dc:date>2024-11-04T08:59:38Z</dc:date>
    </item>
  </channel>
</rss>

