Registration Callback URL - OIDC

I have successfully configured the OIDC and is working as expected. Then I configured the ‘registration_callback_url’ which is in my case a Node-RED instance. I see the post request comming, which includes the ‘user_id’. Now, the only thing I can do is to create eg. a new organization for users which are not yet registered. But how could I implement a fuctionality to automatically onboard e.g. an administration user or add a new user to a specific organization? Isn’t there a posibillity to add more information to this POST request, e.g. like group or other metadata comming from the OIDC provider?
Would like to here what others think about that…

Hello @HofIoT ,

For the registration call back: the user id is in the post request is available as a query. If you use Nodered, look at the complete message object, not only the payload. it’s in: msg.req.query.user_id. . let’s assume you want to add every registered used in an organization. I will do it as follows:

1- get an API key. Global key, not an org key.
2- you need to get the user email from the user id. sent a post request to:
https://chirpstack.example.com/api/users/ + msg.req.query.user_id
3- use the email to create an organization. in nodered you can give the org a name as the email. example: firstname.lastname@example.com → create an org with name: firstname-lastname. you can user nodered to play with that:

msg_n.payload =  {
  "organization": {
    "canHaveGateways": true,
    "displayName": ((msg.payload.user.email).split("@"))[0].replace(/\./g, "-") ,
    "maxDeviceCount": 0,
    "maxGatewayCount": 0,
    "name": ((msg.payload.user.email).split("@"))[0].replace(/\./g, "-")
  }
}
  1. add the user to the org:

msg_n.payload ={
  "organizationUser": {
    "email": msg.email,
    "isAdmin" : true
  }
}

Here is the nodered flow: Don’t use my token :slight_smile:

[{"id":"47cc054a.b24424","type":"http in","z":"f6f2187d.f17ca8","name":"","url":"/test","method":"post","upload":false,"swaggerDoc":"","x":120,"y":140,"wires":[["f39cb2d2.418f9","a6c3d95b.3c0a2"]]},{"id":"a6c3d95b.3c0a2","type":"http response","z":"f6f2187d.f17ca8","name":"","statusCode":"","headers":{},"x":290,"y":120,"wires":[]},{"id":"894b4bee.b4816","type":"debug","z":"f6f2187d.f17ca8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1070,"y":660,"wires":[]},{"id":"1847428b.27790d","type":"group","z":"f6f2187d.f17ca8","name":"Get email from user_id","style":{"label":true},"nodes":["f39cb2d2.418f9","46ecfdfc.25f2d4"],"x":154,"y":219,"w":192,"h":122},{"id":"f39cb2d2.418f9","type":"function","z":"f6f2187d.f17ca8","g":"1847428b.27790d","name":"","func":"var msg_n ={}\n\nmsg_n.url = \"https://chirpstack.example.de/api/users/\" + msg.req.query.user_id\n\nmsg_n.headers = {\n    \"Grpc-Metadata-Authorization\" : \"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGert5X2lkIjoiM2QwYzFmOWItYWU4Ni00NerLTgyZTEtertzerTI0YjQ2MzM2IiwiYXVkIjoiYXMiLCJpc3MiOiJhcyIsIm5iZiI6MTYyMzg4ODYwOSwic3ViIjoiYXBpX2tleSJ9.GvJQlyJo0G7ZCwrBHSptRMdtgH8IuZ0Ne_alKo52hZU\",\n    \"Content-Type\" : \"application/json\"\n}\n\n\nreturn msg_n;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":240,"y":260,"wires":[["46ecfdfc.25f2d4"]]},{"id":"46ecfdfc.25f2d4","type":"http request","z":"f6f2187d.f17ca8","g":"1847428b.27790d","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":250,"y":300,"wires":[["86dcfddc.a736d8"]]},{"id":"6e14b8c6.0877a","type":"group","z":"f6f2187d.f17ca8","name":"add the user to the organization","style":{"label":true},"nodes":["2aa2015e.5f0ae6","6f9973da.5e6e14"],"x":654,"y":559,"w":205,"h":122},{"id":"2aa2015e.5f0ae6","type":"function","z":"f6f2187d.f17ca8","g":"6e14b8c6.0877a","name":"","func":"var org_id = msg.payload.id\n\nvar msg_n ={}\nmsg_n.headers = {\n    \"Grpc-Metadata-Authorization\" : \"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGera2V5X2lkIjoiM2QwYzFmOWItYWU4Ni00NDU5LTgyZTEtMertzTI0YjQ2MzM2IiwiYXVkIjoiYXMiLCJpc3MiOiJhcyIsIm5iZiI6MTYyMzg4ODYwOSwic3ViIjoiYXBpX2tleSJ9.GvJQlyJo0G7ZCwrBHSptRMdtgH8IuZ0Ne_alKo52hZU\",\n    \"Content-Type\" : \"application/json\"\n}\n\nmsg_n.payload ={\n  \"organizationUser\": {\n    \"email\": msg.email,\n    \"isAdmin\" : true\n  }\n}\n\nmsg_n.url = \"https://chirpstack.example.de/api/organizations/\" + org_id + \"/users\"\n\nreturn msg_n;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":740,"y":600,"wires":[["6f9973da.5e6e14"]]},{"id":"6f9973da.5e6e14","type":"http request","z":"f6f2187d.f17ca8","g":"6e14b8c6.0877a","name":"","method":"POST","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":750,"y":640,"wires":[["894b4bee.b4816"]]},{"id":"ba3bfa67.e82898","type":"group","z":"f6f2187d.f17ca8","name":"Create an organization for the new user","style":{"label":true},"nodes":["de571dff.5d7918","86dcfddc.a736d8"],"x":374,"y":399,"w":254,"h":142},{"id":"de571dff.5d7918","type":"http request","z":"f6f2187d.f17ca8","g":"ba3bfa67.e82898","name":"","method":"POST","ret":"obj","paytoqs":"ignore","url":"https://chirpstack.example.de/api/organizations","tls":"","persist":false,"proxy":"","authType":"","x":470,"y":500,"wires":[["2aa2015e.5f0ae6"]]},{"id":"86dcfddc.a736d8","type":"function","z":"f6f2187d.f17ca8","g":"ba3bfa67.e82898","name":"","func":"var msg_n = {}\n\nmsg_n.headers = {\n    \"Grpc-Metadata-Authorization\" : \"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJerztrV5X2lertzterzeWItYWU4Ni00NDU5LTgyZTEtMzertzYjQ2MzM2IiwiYXVkIjoiYXMiLCJpc3MiOiJhcyIsIm5iZiI6MTYyMzg4ODYwOSwic3ViIjoiYXBpX2tleSJ9.GvJQlyJo0G7ZCwrBHSptRMdtgH8IuZ0Ne_alKo52hZU\",\n    \"Content-Type\" : \"application/json\"\n}\n\n\n\nmsg_n.payload =  {\n  \"organization\": {\n    \"canHaveGateways\": true,\n    \"displayName\": ((msg.payload.user.email).split(\"@\"))[0].replace(/\\./g, \"-\") ,\n    \"maxDeviceCount\": 0,\n    \"maxGatewayCount\": 0,\n    \"name\": ((msg.payload.user.email).split(\"@\"))[0].replace(/\\./g, \"-\")\n  }\n}\n\n\nmsg_n.user_id = msg.payload.user.id\nmsg_n.email = msg.payload.user.email\n\nreturn msg_n;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":460,"y":440,"wires":[["de571dff.5d7918"]]}]
1 Like

Hi,
I know how to get the user_id, that was not the problem.
I would like to be able to do following:

  • LDAP users already available in keycloak and added to role “chirpstack-admin” should be added as admin users
  • All other users, which are new to chirpstack and to keycloak could be onboarded as you described

So having additional information about the user (group, roles,…) would be helpful in the POST request, to onboard users. I think it is possible to get the group, roles, etc. from the keycloak API, so that would be a workaround.

Is this information (groups, roles, etc.) always available in OpenID Connect claims or is this in a proprietary format that can be different per OpenID Connect provider?

Hi @brocaar,
yes, I think it should be possible adding the user information included in the token to the post request. I’m far away from beeing an openid expert :-D, but see here.

Cheers

I’m sure it will be possible to add this, but is all this information is included per OIDC specification?
As far as I know, these are the standard claims per specification:

https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims

@HofIoT Hi, I was wondering for you to get OIDC working in a general sense, how did you handle the email_verified field? My Organization uses Azure, and it seems that to send the token everything is stringified. So the true value will be stringified to “true” and on the ChirpStack side it seems the code cannot unmarshall that.

Did you face similar or were you able to receive the value as non-string true?