Skip to main content
Woohoo! Qlik Community has won “Best in Class Community” in the 2024 Khoros Kudos awards!
Announcements
Nov. 20th, Qlik Insider - Lakehouses: Driving the Future of Data & AI - PICK A SESSION
cancel
Showing results for 
Search instead for 
Did you mean: 
LorisLombardo87
Partner - Contributor III
Partner - Contributor III

JWT 401 unauthorized

Hi all,

i'm trying to login to qlik using a JWT token but when i try to post to https://horsadev.eu.qlikcloud.com/login/jwt-session with the the web integration id and the bearer token i get the following error.

LorisLombardo87_0-1715252504937.png

the token is made up like this:

LorisLombardo87_2-1715252675807.png

user details: name sub and email are the exactly like the console.

any idea of what can go wrong here?

 

thanks,

Loris

Labels (3)
15 Replies
mpc
Partner - Specialist II
Partner - Specialist II

Hi, 

Can you check if the token isn't expired yet ? 

Kind regard

From Next Decision and mpc with love
It helps, like it, It solves, mark it
LorisLombardo87
Partner - Contributor III
Partner - Contributor III
Author

thanks for the suggestion Mpc

the token is created with jsonwebtoken I've tried various configurations of expiresIn from 30s to 60m and it is anyway consumed just after its creation, always the same result unfortunately.

Loris

mpc
Partner - Specialist II
Partner - Specialist II

Ok, I assume you've followed this guide: https://community.qlik.com/t5/Member-Articles/Enhanced-Guide-Embedding-Qlik-Cloud-Content-with-JWT/t...

 

From Next Decision and mpc with love
It helps, like it, It solves, mark it
LorisLombardo87
Partner - Contributor III
Partner - Contributor III
Author

no i haven't, there are so many qlik guides on this topic on line 😅...

the interesting bits on that guide though is the mention of the sub field, I've used the one that I can get clicking on the i icon in the users list.

is it the same as the one I can get with https://yourcloudtenant/api/v1/users/me ?

in general what should this sub field (claim) be?

 

mpc
Partner - Specialist II
Partner - Specialist II

You should use the one provided by the URL its return. It's not the one you cand find on the (i) icon in the QMC. 
Moreover, in the final script, you will use ttps://yourcloudtenant/api/v1/users/me to affect the right sub to the user who attempt to log in. 

From Next Decision and mpc with love
It helps, like it, It solves, mark it
LorisLombardo87
Partner - Contributor III
Partner - Contributor III
Author

just to be 100% clear shall I use the one highlighted in red here ?

LorisLombardo87_0-1715260210550.png

 

mpc
Partner - Specialist II
Partner - Specialist II

Yes, it's not the good one, you shoud use the Qlik one beggining by 6 in your screnshot

 

From Next Decision and mpc with love
It helps, like it, It solves, mark it
LorisLombardo87
Partner - Contributor III
Partner - Contributor III
Author

I think the issue might be somewhere else, the error message doesn't change if I add one or the other.

if i look at that guide i cannot see any other suspect element...

any other suggestion ?

alex_colombo
Employee
Employee

Hey @LorisLombardo87  , token seems to be correct. I'm sharing how I create it with jsonwebtoken.

Can you post your JWT IdP configuration set in Management Console and you HTTP request?

const private_key = fs.readFileSync("./key/privatekey.pem", "utf8");

const tenantHost = 'saas.qlikcloud.com';

const id = {
    email: `email@qlik.com`,
    name: "Alex Colombo",
    sub: `idp_subject`
};

const signingOptions = {
    keyid: "keyId",
    algorithm: "RS256",
    issuer: "saas.qlikcloud.com",
    expiresIn: "1m",
    notBefore: "0s",
    audience: "qlik.api/login/jwt-session",
};

const payload = {
    jti: crypto.randomBytes(16).toString("hex"),
    sub: id.sub,
    subType: "user",
    email_verified: true,
    email: id.email,
    name: id.name,
    groups: id.groups,
};

const token = jsonwebtoken.sign(payload, private_key, signingOptions);

console.log(token);

setTimeout(async () => {
    const resp = await fetch(`https://${tenantHost}/login/jwt-session`, {
        method: "POST",
        headers: {
        Authorization: `Bearer ${token}`,
        },
    });
    const resp2 = await fetch(`https://${tenantHost}/api/v1/items?resourceType=app`, {
        headers: {
        Authorization: `Bearer ${token}`,
        },
    });

    console.log('resp status: ', resp2.status)
}, 200)