Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Commit

Permalink
Add support for new keycloak device auth flow
Browse files Browse the repository at this point in the history
- Legacy flow is still supported

closes #64

Signed-off-by: Oguzcan Kirmemis <[email protected]>
  • Loading branch information
oguzcankirmemis committed Sep 7, 2023
1 parent 6088fc5 commit c7888e6
Showing 1 changed file with 52 additions and 14 deletions.
66 changes: 52 additions & 14 deletions lib/authService/authenticate.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,38 @@ function verifyAndDecodeToken(token) {
});
}

class Authenticate {
function getRealm(token) {
// issuer has to contain realm id, e.g.: http://<keycloak-url>/auth/realms/iff
const parts = token.iss.split("/");
return iss[iss.length - 1];
}

function validate(token) {
let type = token.type;
let did = token.device_id;
if (!type || !did) {
return false;
}
if (type !== "device" || did !== username) {
return false;
}
return true;
}

function legacyValidate(token) {
let accounts = token.accounts;
let type = token.type;
let did = token.sub;
if (!accounts || !type || !did) {
return false;
}
if (accounts.length !== 1 || accounts[0].role !== "device" || type !== "device" || did !== username) {
return false;
}
return true;
}

class Authenticate {
constructor(config, logger){
this.config = config;
this.logger = logger;
Expand Down Expand Up @@ -63,22 +93,30 @@ class Authenticate {
res.sendStatus(400);
return;
}
// check whether accounts contains only one element and role is device
var accounts = decoded_token.accounts;
var did = decoded_token.sub;
if (accounts === undefined || did === undefined || accounts.length !== 1 || accounts[0].role !== "device" || did !== username) {
if (!validate(decoded_token) && !legacyValidate(decoded_token)) {
res.sendStatus(400);
return;
}
var accountId = accounts[0].id;
//put account/device into the list of accepted topics
var key = accountId + "/" + did;
await this.cache.setValue(key, "acl", true);

// For SparkplugB put account/gateway(node) into the list of accepted topics to authenticate Node/gateway messages
if (decoded_token.gateway !== undefined ||decoded_token.gateway === null) {
var gatewayKey=accountId + "/"+ decoded_token.gateway;
await this.cache.setValue(gatewayKey, "acl", true);
// check whether accounts contains only one element and role is device
var accounts = decoded_token.accounts;
var did = decoded_token.device_id ? decoded_token.device_id : decoded_token.sub;
var accountId = accounts ? accounts[0].id : null;
let realm = getRealm(decoded_token);
// put realm/device into the list of accepted topics
await this.cache.setValue(realm + "/" + did, "acl", true);
// put account/device into the list of accepted topics (legacy)
if (accountId) {
var key = accountId + "/" + did;
await this.cache.setValue(key, "acl", true);
}
// For SparkplugB put (legacy) account/gateway(node) and realm/gateway(node) into the list of accepted topics to authenticate Node/gateway messages
if (decoded_token.gateway !== undefined || decoded_token.gateway === null) {
if (accountId) {
var legacyGatewayKey = accountId + "/" + decoded_token.gateway;
await this.cache.setValue(legacyGatewayKey, "acl", true);
}
let gatewayKey = realm + "/" + decoded_token.gateway;
await this.cache.setvalue(gatewayKey, "acl", true);
}
res.sendStatus(200);
}
Expand Down

0 comments on commit c7888e6

Please sign in to comment.