Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
On the on-prem version of Qlik Sense, you can setup a User Directory Connector which imports users from a directory, such as Active Directory, or a flat file i.e. spreadsheet. In the SaaS world, this doesnt exist. This is fine when using Qlik Account as the identity provider (IDP) but when using Azure AD, users are not avaialble as a user until they log in for the first time, meaning a two step process for onboarding.
I was wondering if it was possible to use App Automations to create an Automation to create Users in SaaS based on an Azure AD group or the whole directory
Looking at the blocks we have, I don't see anything for Creating users, but could use the Raw block POST request in conjunction with this: users | Qlik Developer Portal
However, I'm not seeing anything to talk to Azure AD. Could we use the Call URL block, and grab data from Microsoft Graph (see List users - Microsoft Graph v1.0 | Microsoft Docs for users and List members - Microsoft Graph v1.0 | Microsoft Docs for groups) via a GET call?
Aware this post has turned into a bit of a ramble, to summarise, would it be possible to create a User Directory Connector, like similar functionality we have in the on-prem Qlik Sense, using App Automations?
Hi @Carl_Hunter ,
I just attempted the automation that you sent and it appears the content-type of the Raw API request somehow was not application/json. We have modified this block and next time connectors will be deployed, this will be changed so it should be working!
With regards to the Azure AD part of the question. This is not something we currently have planned, but I suggest submitting this to the ideation board to add a Azure AD connector. Link to ideation board: https://community.qlik.com/t5/Ideation/ct-p/qlik-product-insight
As for the Raw API request, this will currently not work as it will need to authenticate to Microsoft Graph and you would need to obtain an access token. The refreshing part of this will not function well. We are adding an OAuth connector to the platform soon so this will be possible using that connector.
So, I've tried to use the Raw API block to create a post request and create a user, however, I keep getting an error re missing fields
Error:
{ "error": "Error calling endpoint \"Qlik Cloud Services - Raw API Request\"", "endpoint": { "name": "Raw API Request", "datasource": "Qlik Cloud Services" }, "request": { "url": "https://{domain}/api/v1/users", "method": "GET" }, "response": { "status": 400, "body": { "errors": [ { "title": "Missing required fields", "code": "USERS-1", "status": 400, "meta": { "missingField": "name", "requiredFields": [ "name", "subject", "tenantId" ] } } ], "traceId": "698f9a07e901847d9500d42b9c59a1c0" } }, "external error": true }
and here's my input
{ "path": "users", "HTTP_method": "POST", "body": { "name": "Carl Test User", "tenantId": "R2ZYn-t8RPv9kcTwGgTX5cUWUlt8bNZY", "subject": "test_test_test_123" }, "query_parameters": [], "blendr_on_error": "warning" }
where you can clearly see name is being passed in the body of the POST request - above in red.
I've tried the same block but creating a Space, instead of a User, and it works fine - see below, 3rd step
and here is the output json
{"block":"getCurrentUserId","index":1,"in_count":1,"timestamp_start":1641401175874563,"timestamp":1641401175942632,"memory_usage":6618912,"out_count":1,"out":"m3QcAy50Tb24X0cUoFuSz-r9D3TVyNNf","in":{"blendr_on_error":"stop"}} {"block":"getUser","index":1,"in_count":2,"timestamp_start":1641401175943319,"timestamp":1641401176012848,"memory_usage":6627224,"out_count":12,"out":{"id":"m3QcAy50Tb24X0cUoFuSz-r9D3TVyNNf","name":"Carl Hunter","tenantId":"R2ZYn-t8RPv9kcTwGgTX5cUWUlt8bNZY","status":"active","email":"carl.hunter@tsg.com","preferredZoneinfo":"Europe\/London","preferredLocale":"en","roles":["Developer","TenantAdmin","SharedSpaceCreator","ManagedSpaceCreator","AnalyticsAdmin","DataSpaceCreator","DataAdmin"],"subject":"TSG\\carl.hunter","created":"2020-12-21T13:43:05.216Z","lastUpdated":"2021-12-30T16:54:56.650Z","links":{"self":{"href":"https:\/\/tsgltd.eu.qlikcloud.com\/api\/v1\/users\/m3QcAy50Tb24X0cUoFuSz-r9D3TVyNNf"}}},"in":{"user_id":"m3QcAy50Tb24X0cUoFuSz-r9D3TVyNNf","blendr_on_error":"stop"}} {"block":"rawAPIRequest3","index":1,"in_count":5,"timestamp_start":1641401176013098,"timestamp":1641401176145313,"memory_usage":6632680,"out_count":11,"out":{"id":"61d5cb58354678a505dcfa25","type":"shared","ownerId":"m3QcAy50Tb24X0cUoFuSz-r9D3TVyNNf","tenantId":"R2ZYn-t8RPv9kcTwGgTX5cUWUlt8bNZY","name":"carltest123abc","description":"carls description","meta":{"actions":["read","create","update","delete"],"roles":[],"assignableRoles":["consumer","dataconsumer","facilitator","producer"]},"links":{"self":{"href":"https:\/\/tsgltd.eu.qlikcloud.com\/api\/v1\/spaces\/61d5cb58354678a505dcfa25"},"assignments":{"href":"https:\/\/tsgltd.eu.qlikcloud.com\/api\/v1\/spaces\/61d5cb58354678a505dcfa25\/assignments"}},"createdAt":"2022-01-05T16:46:16.135Z","createdBy":"m3QcAy50Tb24X0cUoFuSz-r9D3TVyNNf","updatedAt":"2022-01-05T16:46:16.135Z"},"in":{"path":"spaces","HTTP_method":"POST","body":{"name":"carltest123abc","description":"carls description","type":"shared"},"query_parameters":[],"blendr_on_error":"stop"}} {"block":"rawAPIRequest4","index":1,"in_count":5,"timestamp_start":1641401176145531,"timestamp":1641401176210830,"memory_usage":6669344,"error":{"error":"Error calling endpoint \"Qlik Cloud Services - Raw API Request\"","endpoint":{"name":"Raw API Request","datasource":"Qlik Cloud Services"},"request":{"url":"https:\/\/{domain}\/api\/v1\/users","method":"GET"},"response":{"status":400,"body":{"errors":[{"title":"Missing required fields","code":"USERS-1","status":400,"meta":{"missingField":"name","requiredFields":["name","subject","tenantId"]}}],"traceId":"b2a6cbd5065631f6c30954ef207b3dca"}},"external error":true},"in":{"path":"users","HTTP_method":"POST","body":{"name":"Carl Test User","tenantId":"R2ZYn-t8RPv9kcTwGgTX5cUWUlt8bNZY","subject":"test_test_test_123"},"query_parameters":[],"blendr_on_error":"warning"}}
I've attached the workspace json too.
I've had another look at this, and by using a Call URL block in POST mode, I have been able to create a user by calling the exact same header/params as when this doesn't work via the Raw API block.
See below screenshot and in/out json responses. User is called Carl Test User
In:
{ "url": "https://tsgltd.eu.qlikcloud.com/api/v1/users", "params": { "name": "Carl Test User", "tenantId": "R2ZYn-t8RPv9kcTwGgTX5cUWUlt8bNZY", "subject": "test_test_test_123" }, "headers": { "Authorization": "Bearer BEARER_TOKEN_HAS_BEEN_REMOVED", "Content-type": "application/json" }, "method": "POST", "timeout": 60, "encoding": null, "options": { "capitalize_headers": true, "full_response": false }, "blendr_on_error": "warning" }
Out:
{ "id": "RweM1nZsQXOM4hj4GPUbsI06HTSoVct0", "name": "Carl Test User", "tenantId": "R2ZYn-t8RPv9kcTwGgTX5cUWUlt8bNZY", "status": "active", "roles": [], "subject": "test_test_test_123", "created": "2022-01-05T22:13:35.758Z", "lastUpdated": "2022-01-05T22:13:35.758Z", "links": { "self": { "href": "https://tsgltd.eu.qlikcloud.com/api/v1/users/RweM1nZsQXOM4hj4GPUbsI06HTSoVct0" } } }
Hi @Carl_Hunter ,
I just attempted the automation that you sent and it appears the content-type of the Raw API request somehow was not application/json. We have modified this block and next time connectors will be deployed, this will be changed so it should be working!
With regards to the Azure AD part of the question. This is not something we currently have planned, but I suggest submitting this to the ideation board to add a Azure AD connector. Link to ideation board: https://community.qlik.com/t5/Ideation/ct-p/qlik-product-insight
As for the Raw API request, this will currently not work as it will need to authenticate to Microsoft Graph and you would need to obtain an access token. The refreshing part of this will not function well. We are adding an OAuth connector to the platform soon so this will be possible using that connector.
Hey @MarkGeurtsen thanks for fixing the bug, my workaround of using Call URL block worked fine also 🙂
Re Azure AD and MS Graph, yes, I will add the idea to the ideation forum, however, by using the Call URL block in POST and GET mode, I've managed to create an automation which calls MS Graph (using machine to machine authorisation flow - Get access without a user - Microsoft Graph | Microsoft Docs - rather than OAuth), gets a bearer token, then uses that to pull User info - I just been to loop over and check if exists in SaaS and if not, create a user - easy eh? 🙂