Skip to main content
Announcements
Join us at Qlik Connect for 3 magical days of learning, networking,and inspiration! REGISTER TODAY and save!
cancel
Showing results for 
Search instead for 
Did you mean: 
eric_careta
Partner - Contributor III
Partner - Contributor III

Trouble send direct request to Repository API

Hi everyone,

We have a server with Qlik Sense installed (A) and another server (B) from which we want to run a powershell program that performs instructions from server A with the qrs API.

The problem is that we can't connect using the certificate and sending a direct request to the repository API.

Following the steps described in https://community.qlik.com/t5/Official-Support-Articles/Qlik-Sense-QRS-API-using-Xrfkey-header-in-Po...
we have to connect using the Method 2, having the certificate exported and installed as indicated in
https://community.qlik.com/t5/Official-Support-Articles/Export-client-certificate-and-root-certifica...
and with port 4242 of server A open (verified by testing the telnet statement on server B indicated at
https://superuser.com/questions/339107/how-to-telnet-to-an-ip-address-on-a-specific-port
) if we execute the following program through the console in administrator mode:

 

 

$Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
$Compiler=$Provider.CreateCompiler()
$Params=New-Object System.CodeDom.Compiler.CompilerParameters
$Params.GenerateExecutable=$False
$Params.GenerateInMemory=$True
$Params.IncludeDebugInformation=$False
$Params.ReferencedAssemblies.Add("System.DLL") | Out-Null

$TASource=@'
  namespace Local.ToolkitExtensions.Net.CertificatePolicy{
    public class TrustAll : System.Net.ICertificatePolicy {
      public TrustAll() {
      }
      public bool CheckValidationResult(System.Net.ServicePoint sp,
        System.Security.Cryptography.X509Certificates.X509Certificate cert,
        System.Net.WebRequest req, int problem) {
        return true;
      }
    }
  }
'@
$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
$TAAssembly=$TAResults.CompiledAssembly

## We now create an instance of the TrustAll and attach it to the ServicePointManager
$TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
[System.Net.ServicePointManager]::CertificatePolicy=$TrustAll

$hdrs=@{}
$hdrs.Add("X-Qlik-xrfkey","12345678qwertyui")
$hdrs.Add("X-Qlik-User","UserDirectory=internal;UserId=sa_repository")
$hdrs.Add("Content-Type","application/json")
$cert = Get-ChildItem -Path "Cert:\LocalMachine\Root"| Where {$_.Subject -like '*Eagle.uvedom*'}
write $cert
$url=https://urlserverA:4242/qrs/license/analyzeraccesstype/full?xrfkey=12345678qwertyui
$response=Invoke-RestMethod -Uri $url -Method Get -Headers $hdrs -UseDefaultCredentials -Certificate $cert
$content=$response
write $ content
       
$url= https:// urlserverA:4242/qrs/task/start/synchronous?name=TaskTest&xrfkey=12345678qwertyui
$response=Invoke-RestMethod -Uri $url -Method Post -Headers $hdrs -UseDefaultCredentials -Certificate $cert
$ content =$response.value

 


The execution is this:

eric_careta_1-1676140853384.png

Invoke-restmethod: The remote server returned an error: (403) Forbidden.

What could be happening?

Labels (1)
  • API

1 Solution

Accepted Solutions
Marc
Employee
Employee

The issue with the above is the certificate you are using. The Subject on the certificate indicates that it is the Qlik Sense Root CA Certificate, you need to use the one with the subject "CN=QlikClient" as per the community post you referenced.

$cert = Get-ChildItem -Path "Cert:\CurrentUser\My" | Where {$_.Subject -like '*QlikClient*'}

 then there is a whole lot of code for Provider, Compiler etc that seems overly complex.

and your "Invoke-RestMethod" calls are trying to use the certificate & provide default credentials (-UseDefaultCredentials)


Have a look at the following, this should do what you are after.

if (-not ([System.Management.Automation.PSTypeName]'TrustAllCertsPolicy').Type) {
    Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
    ServicePoint srvPoint, X509Certificate certificate,
    WebRequest request, int certificateProblem) {
    return true;
    }
}
"@
}
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

##Cert should be in a Personal Store (either CurrentUser or LocalMachine)\My
#$cert = Get-ChildItem -Path "Cert:\CurrentUser\My" | Where-Object {$_.Subject -eq 'CN=QlikClient'}
#If you have more that one Sense Environment Certificate
$cert = Get-ChildItem -Path "Cert:\LocalMachine\My" | Where-Object{$_.Subject -eq 'CN=QlikClient' -and $_.Issuer -like '*Eagle.uvedom*'}|Sort-Object -Property NotAfter -Descending|Select-Object -First 1
Write-Output $cert

$XRFKey = '12345678qwertyui'
$hdrs=@{}
$hdrs.Add("X-Qlik-xrfkey","$($XRFKey)")
$hdrs.Add("X-Qlik-User","UserDirectory=internal;UserId=sa_repository")
$hdrs.Add("Content-Type","application/json")

$url="https://urlserverA:4242/qrs/license/analyzeraccesstype/full?xrfkey=$($XRFKey)"
$response=Invoke-RestMethod -Uri $url -Method Get -Headers $hdrs -Certificate $cert
$content=$response
Write-Output $content



 

As an alternative, you could use one of the existing PowerShell modules designed to communicate with the QRS APIs

QlikSenseCLI or Qlik-Cli-Windows  

both of which can be installed by simply running the command 

Install-Module QlikSenseCLI -Scope CurrentUser
#or
Install-Module Qlik-CLI -Scope CurrentUser

View solution in original post

2 Replies
Marc
Employee
Employee

The issue with the above is the certificate you are using. The Subject on the certificate indicates that it is the Qlik Sense Root CA Certificate, you need to use the one with the subject "CN=QlikClient" as per the community post you referenced.

$cert = Get-ChildItem -Path "Cert:\CurrentUser\My" | Where {$_.Subject -like '*QlikClient*'}

 then there is a whole lot of code for Provider, Compiler etc that seems overly complex.

and your "Invoke-RestMethod" calls are trying to use the certificate & provide default credentials (-UseDefaultCredentials)


Have a look at the following, this should do what you are after.

if (-not ([System.Management.Automation.PSTypeName]'TrustAllCertsPolicy').Type) {
    Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
    ServicePoint srvPoint, X509Certificate certificate,
    WebRequest request, int certificateProblem) {
    return true;
    }
}
"@
}
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

##Cert should be in a Personal Store (either CurrentUser or LocalMachine)\My
#$cert = Get-ChildItem -Path "Cert:\CurrentUser\My" | Where-Object {$_.Subject -eq 'CN=QlikClient'}
#If you have more that one Sense Environment Certificate
$cert = Get-ChildItem -Path "Cert:\LocalMachine\My" | Where-Object{$_.Subject -eq 'CN=QlikClient' -and $_.Issuer -like '*Eagle.uvedom*'}|Sort-Object -Property NotAfter -Descending|Select-Object -First 1
Write-Output $cert

$XRFKey = '12345678qwertyui'
$hdrs=@{}
$hdrs.Add("X-Qlik-xrfkey","$($XRFKey)")
$hdrs.Add("X-Qlik-User","UserDirectory=internal;UserId=sa_repository")
$hdrs.Add("Content-Type","application/json")

$url="https://urlserverA:4242/qrs/license/analyzeraccesstype/full?xrfkey=$($XRFKey)"
$response=Invoke-RestMethod -Uri $url -Method Get -Headers $hdrs -Certificate $cert
$content=$response
Write-Output $content



 

As an alternative, you could use one of the existing PowerShell modules designed to communicate with the QRS APIs

QlikSenseCLI or Qlik-Cli-Windows  

both of which can be installed by simply running the command 

Install-Module QlikSenseCLI -Scope CurrentUser
#or
Install-Module Qlik-CLI -Scope CurrentUser
eric_careta
Partner - Contributor III
Partner - Contributor III
Author

I've tried to import certificate with QlikClient subject and it works.

The initial problem it was I have another qlik certificate of another server and it collapse with the new one. I change the installation directory of the new one with the subject of QlikClient and it works!

Thanks a lot @Marc 

Cheers