<?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 Re: 403/XSRF when calling QPS API  (iframe mashup code using python inside ;-) in Integration, Extension &amp; APIs</title>
    <link>https://community.qlik.com/t5/Integration-Extension-APIs/403-XSRF-when-calling-QPS-API-iframe-mashup-code-using-python/m-p/2093799#M18856</link>
    <description>&lt;P&gt;Yes, I changed the XRF_KEY to be 16 character length and it worked like a charm.&lt;/P&gt;
&lt;P&gt;I marked your answer as the solution, and modified the code with an assertion, so other people will be able to reuse this code without stumbling with the same issue.&lt;/P&gt;
&lt;P&gt;BTW, I checked also that after cleaning qliksense cookies, it doesn't show the mashup. It shows an squared icon (with an X inside) instead.&lt;/P&gt;
&lt;P&gt;Thanks a lot&amp;nbsp;&lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/29425"&gt;@Damien_V&lt;/a&gt;&amp;nbsp; for your help, and for the clarification regarding the TargetId parameter.&lt;/P&gt;</description>
    <pubDate>Fri, 14 Jul 2023 08:14:39 GMT</pubDate>
    <dc:creator>virilo_tejedor</dc:creator>
    <dc:date>2023-07-14T08:14:39Z</dc:date>
    <item>
      <title>403/XSRF when calling QPS API  (iframe mashup code using python inside ;-)</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/403-XSRF-when-calling-QPS-API-iframe-mashup-code-using-python/m-p/2093462#M18850</link>
      <description>&lt;DIV&gt;I'm trying to use QPS API to get a ticket for to be used in a Flask web server by using a mashup iframe.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;When I run the attached code:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;SPAN&gt; - It doesn't return me any ticket, it returns a 403 error instead due to XSRF&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;SPAN&gt; - It offers me a login form despite the wrong ticket (virtual proxy configured to use form authentication)&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;SPAN&gt; - Once I log in the iframe, it shows the mashup correctly&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;My setup:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;SPAN&gt; - Qlik Sense Server Enterprise 2022&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;SPAN&gt; - Virtual proxy: ( mostly from &lt;A href="https://www.youtube.com/watch?v=qf4uzB8mBuo&amp;amp;list=PLdnQXZq2xRoBblWlKxGws3WVaJ1GU8S41&amp;amp;index=34" target="_self"&gt;this video&lt;/A&gt; )&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; - Annonymous access mode: no&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; - Authentication method: Ticket&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; - Windows authentication pattern: forms&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; - has secure attribute (https): checked&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; - SameSite attribute (https): None&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; - Hosts white list: empty (using just one QS server)&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;SPAN&gt; - I created cert/key/root files exported from the QMC/Certificates (weird, because once it were exported I stopped watching them listed at QMC/Certificates)&amp;nbsp;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;SPAN&gt; - Certificates were converted to .pem using openssl.&amp;nbsp; &amp;nbsp;"client.pem" file contains both: a private key and a certificate&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;SPAN&gt; - Engine\Settings.ini configured with:&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-30px"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; EnableTTL=1&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; SessionTTL=30&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="lia-indent-padding-left-60px"&gt;&lt;SPAN&gt; (and extra CR-LF line)&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Why am I receiving this 403 error?&amp;nbsp; How could I solve it?&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Why is it still possible to use the mashup whithout any proper ticket?&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;What is the TargetId parameter used for?&amp;nbsp; I can see it on this &lt;A href="https://community.qlik.com/t5/Official-Support-Articles/Node-js-Send-a-ticket-request-Qlik-Sense-Proxy-API/tac-p/2093457#M9681" target="_self"&gt;node.js example&lt;/A&gt;, but I can't see it is being used in the &lt;A href="https://community.qlik.com/t5/Official-Support-Articles/Qlik-Sense-Generate-a-ticket-with-Qlik-proxy-API-Powershell/ta-p/1711178" target="_self"&gt;Powershell example&lt;/A&gt;.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The output log:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;LI-CODE lang="markup"&gt;InsecureRequestWarning: Unverified HTTPS request is being made to host 'analytics.mycompany.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
127.0.0.1 - - [13/Jul/2023 11:00:28] "GET / HTTP/1.1" 200 -
QPS_API_URL https://analytics.mycompany.com:4243/qps/testmashup/ticket?xrfkey=123456789abcdef
ticket:  XSRF prevention check failed. Possible XSRF discovered.
response:  &amp;lt;Response [403]&amp;gt;
response.reason:  Forbidden&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The python code:&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;from flask import Flask, render_template_string
import requests

app = Flask(__name__)

QLIK_SENSE_SERVER_DOMAIN='analytics.mycompany.com'

USER_DIRECTORY = 'MYCOMPANYAD'
USER_ID = 'myuser'  # Root Admin user

XRF_KEY = '123456789abcdefg'  # You can change this
PROXY_PREFIX = 'testmashup'  # Your virtual proxy prefix

QPS_API_URL = f"https://{QLIK_SENSE_SERVER_DOMAIN}:4243/qps/{PROXY_PREFIX}/ticket?xrfkey={XRF_KEY}"  
QPS_HEADERS = {   
    'content-type': 'application/json',
    'X-Qlik-xrfkey': XRF_KEY,
    'X-Qlik-user': f'UserDirectory={USER_DIRECTORY};UserId={USER_ID}'
        
}

assert len(XRF_KEY)==16, f'''XRF_KEY ERROR.  XRF_KEY={XRF_KEY} len={len(XRF_KEY)}

XRF_KEY must be alphanumeric and 16 characters length.

See https://community.qlik.com/t5/Integration-Extension-APIs/403-XSRF-when-calling-QPS-API-iframe-mashup-code-using-python/m-p/2093779/highlight/true#M18855 '''



MASHUP_URL = f"https://{QLIK_SENSE_SERVER_DOMAIN}/{PROXY_PREFIX}/extensions/TestMashup/TestMashup.html" 

@app.route('/')
def serve_page():
    ticket = get_ticket(USER_DIRECTORY, USER_ID)
    iframe_src=f"{MASHUP_URL}?QlikTicket={ticket}"
    html = f"""&amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html style="height: 100%;"&amp;gt;
    
    &amp;lt;body&amp;gt;
    
    &amp;lt;iframe src="{iframe_src}" frameborder="0" scrolling="yes" seamless="seamless" style="display:block; width:100%; height:100vh;"&amp;gt;&amp;lt;/iframe&amp;gt;
    
    &amp;lt;/html&amp;gt;"""
    return render_template_string(html)

def get_ticket(user_directory, user_id):
    payload = {        
        "UserDirectory": user_directory,
        "UserId": user_id,
        "Attributes": []
        # "TargetId": targetId, # what is actually this targetId ???
        
        
    }
    
    
    response = requests.post(QPS_API_URL, headers=QPS_HEADERS, json=payload, \
                              cert=(r'client.pem', \
                                    r'client.pem'), \
                            verify=False)
    
    # response.raise_for_status()  # Raises stored HTTPError, if one occurred.
    ticket = response.text
    
    print("QPS_API_URL", QPS_API_URL)
    print("ticket: ", ticket)
    print("response: ", response)
    print("response.reason: ", response.reason)
    
    return ticket

if __name__ == "__main__":
    app.run(port=8080)
&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 14 Jul 2023 08:09:40 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/403-XSRF-when-calling-QPS-API-iframe-mashup-code-using-python/m-p/2093462#M18850</guid>
      <dc:creator>virilo_tejedor</dc:creator>
      <dc:date>2023-07-14T08:09:40Z</dc:date>
    </item>
    <item>
      <title>Re: 403/XSRF when calling QPS API  (iframe mashup code using python inside ;-)</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/403-XSRF-when-calling-QPS-API-iframe-mashup-code-using-python/m-p/2093779#M18855</link>
      <description>&lt;P&gt;Hello&amp;nbsp;&lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/16550"&gt;@virilo_tejedor&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV&gt;Why am I receiving this 403 error?&amp;nbsp; How could I solve it?&lt;/DIV&gt;
&lt;DIV&gt;&amp;gt; your XRF key is 15 characters, it needs to be an alphanumeric string that is exactly 16 characters&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Why is it still possible to use the mashup whithout any proper ticket?&lt;/DIV&gt;
&lt;DIV&gt;&amp;gt; It shouldn't be possible unless you already have an active cookie for that virtual proxy in your browser, did you try to clear cache/cookies from the browser and test?&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;What is the TargetId parameter used for?&amp;nbsp;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&amp;gt; Qlik Sense will remember what URL you tried to access before getting redirected to the authentication module and store it in memory as an ID, the mapping between the actual URL and the ID is stored in the Qlik Proxy service memory and cannot be seen directly.&lt;/SPAN&gt;&lt;/DIV&gt;</description>
      <pubDate>Fri, 14 Jul 2023 06:57:57 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/403-XSRF-when-calling-QPS-API-iframe-mashup-code-using-python/m-p/2093779#M18855</guid>
      <dc:creator>Damien_V</dc:creator>
      <dc:date>2023-07-14T06:57:57Z</dc:date>
    </item>
    <item>
      <title>Re: 403/XSRF when calling QPS API  (iframe mashup code using python inside ;-)</title>
      <link>https://community.qlik.com/t5/Integration-Extension-APIs/403-XSRF-when-calling-QPS-API-iframe-mashup-code-using-python/m-p/2093799#M18856</link>
      <description>&lt;P&gt;Yes, I changed the XRF_KEY to be 16 character length and it worked like a charm.&lt;/P&gt;
&lt;P&gt;I marked your answer as the solution, and modified the code with an assertion, so other people will be able to reuse this code without stumbling with the same issue.&lt;/P&gt;
&lt;P&gt;BTW, I checked also that after cleaning qliksense cookies, it doesn't show the mashup. It shows an squared icon (with an X inside) instead.&lt;/P&gt;
&lt;P&gt;Thanks a lot&amp;nbsp;&lt;a href="https://community.qlik.com/t5/user/viewprofilepage/user-id/29425"&gt;@Damien_V&lt;/a&gt;&amp;nbsp; for your help, and for the clarification regarding the TargetId parameter.&lt;/P&gt;</description>
      <pubDate>Fri, 14 Jul 2023 08:14:39 GMT</pubDate>
      <guid>https://community.qlik.com/t5/Integration-Extension-APIs/403-XSRF-when-calling-QPS-API-iframe-mashup-code-using-python/m-p/2093799#M18856</guid>
      <dc:creator>virilo_tejedor</dc:creator>
      <dc:date>2023-07-14T08:14:39Z</dc:date>
    </item>
  </channel>
</rss>

