Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
grangerats
Partner - Contributor III
Partner - Contributor III

How do I create/edit a user account via the QRS API such that the user becomes a member of a Group that can be used in Section Access?

I have seen various information about making User accounts members of Groups within Qlik Sense. I would like to use Groups so that I can use them with the Section Access (Dynamic Data Reduction) functionality. However, I have not been able to successfully get any user setup with anything that Qlik Sense (3.1) recognizes as a Group.

I'm expecting that if I get it right, I'll see "group" in the user info popup, as in this snip of a screen-shot pulled from here. Or, if that UI has changed, I would expect it to show up in a Json user object returned by the QRS API ( /qrs/User/full ).

I have local Windows accounts in the User account list. They are part of local Windows groups (built-in and custom), but none of those groups show up anywhere in the UI nor does any such data get returned in the Json of a User object returned by the QRS API.

I have created new user accounts via the QPS API's Ticket creation endpoint using the qlik-auth-net sample web-app. That sample code suggests that it will set the Group, but it never does; it doesn't even successfully set the attributes. It doesn't matter if the user is created via the ticket or if it matches to an existing account. I even built my own, custom UDC, and had the Users returned by  public IList<UdcEntity> SyncUsers(params string[] usersToFilterOn)  get setup with a AttributeType.Group in the list of UdcAttribute objects returned in each UdcEntity. Still no joy.

I also can successfully create Users through the QRS API. I have done it both directly via the QRS ( {server}:4242/qrs/User ) and indirectly via a Virtual Proxy ( {server}/virtualproxy/qrs/User ). This is the farthest I've gotten with User attributes. Thanks to the default object returned by  /qrs/about/api/default/user  I was able to create a user with the below Json object specified in the "attributes" array, and it was successfully saved. I know it was saved because it was then returned by  /qrs/User/full  as expected. Yet, still no evidence that the User account was a member of what Qlik considers a "Group".

{

    "attributeType": "Group",

    "attributeValue": "TestUserGroup"

}

I'm at a loss at this point. Without Groups, Section Access is an epic fail for my use case. (But if Section Access could be done through Custom Properties, then I could ignore the "Groups" concept entirely.)

1 Solution

Accepted Solutions
grangerats
Partner - Contributor III
Partner - Contributor III
Author

Thanks to pbr, I have a satisfactory answer.

First, as of QlikSense 3.1, there is nothing in the UI that can be used to display group information for a user account. My understanding is that the group information used for authorization (authZ) only exists as part of a login session; nothing is persisted. So the only way QlikSense could display such information would be if there was a way for an admin to view login-session data for any currently logged in accounts. (That would be really, really useful, BTW.)

Section Access uses the values in "USERID" and "GROUP" to determine what user accounts the constraints apply to. For USERID, that's straight-forward: use "{UDC-name}\{User-name}" for the account in QlikSense (e.g. "INTERNAL\SA_SCHEDULER"). For GROUP, the value it's looking for is available only in the login-session. It uses the same set of values accessed via "user.environment.group" when setting up security rules in the QMC.

So if you need to use Groups in Section Access, do whatever it takes to get group information into the "user.environment.group" attribute. It's easy to add this data using the QPS API (Ticket API), but there's no interface to view/edit it once it's there---so that's why I originally thought it wasn't setting anything. It's not persisted, and it doesn't mix with group data that is persisted. (I confirmed that if you set an attribute of type "Group" on a user account via the QRS API, it's irrelevant with regards to Section Access.)

For example. If I create an account like so (remember that the UDC, like the user, doesn't have to exist; it'll create it when the ticket is used to login):

URL:

https://{host}/qps/{virtual-proxy-prefix}/ticket?Xrfkey=0123456789abcdef

HEADERS:

X-Qlik-Xrfkey: 0123456789abcdef

Content-Type: application/json

BODY:

{

      "UserDirectory": "{UDC-name}"

    , "UserId": "{User-name}"

    , "ProxyRestUri": "https://{host}/qps/{virtual-proxy-prefix}/"

    , "TargetId": "{value-from-url-param}"

    , "Attributes": [

          { "Group": "GroupName1" }

        , { "Group": "GroupName2" }

    ]

}

I can allow that user into an App with this load script (as well as allow a reload task to work):

Section Access;

BasicAccess:

LOAD * INLINE [

ACCESS, GROUP, USERID,

USER, GroupName1, *

USER,  *, INTERNAL\SA_SCHEDULER

];

Section Application;

...

And from there, I can add more useful Section Access rules. Like, perhaps, making it so "GroupName2" actually has rules, or using the "OMIT" column to block accounts from seeing data from specific columns loaded in data in "Section Application", etc.  Oh, and, yes, the group name check is case-insensitive.

View solution in original post

3 Replies
grangerats
Partner - Contributor III
Partner - Contributor III
Author

Thanks to pbr, I have a satisfactory answer.

First, as of QlikSense 3.1, there is nothing in the UI that can be used to display group information for a user account. My understanding is that the group information used for authorization (authZ) only exists as part of a login session; nothing is persisted. So the only way QlikSense could display such information would be if there was a way for an admin to view login-session data for any currently logged in accounts. (That would be really, really useful, BTW.)

Section Access uses the values in "USERID" and "GROUP" to determine what user accounts the constraints apply to. For USERID, that's straight-forward: use "{UDC-name}\{User-name}" for the account in QlikSense (e.g. "INTERNAL\SA_SCHEDULER"). For GROUP, the value it's looking for is available only in the login-session. It uses the same set of values accessed via "user.environment.group" when setting up security rules in the QMC.

So if you need to use Groups in Section Access, do whatever it takes to get group information into the "user.environment.group" attribute. It's easy to add this data using the QPS API (Ticket API), but there's no interface to view/edit it once it's there---so that's why I originally thought it wasn't setting anything. It's not persisted, and it doesn't mix with group data that is persisted. (I confirmed that if you set an attribute of type "Group" on a user account via the QRS API, it's irrelevant with regards to Section Access.)

For example. If I create an account like so (remember that the UDC, like the user, doesn't have to exist; it'll create it when the ticket is used to login):

URL:

https://{host}/qps/{virtual-proxy-prefix}/ticket?Xrfkey=0123456789abcdef

HEADERS:

X-Qlik-Xrfkey: 0123456789abcdef

Content-Type: application/json

BODY:

{

      "UserDirectory": "{UDC-name}"

    , "UserId": "{User-name}"

    , "ProxyRestUri": "https://{host}/qps/{virtual-proxy-prefix}/"

    , "TargetId": "{value-from-url-param}"

    , "Attributes": [

          { "Group": "GroupName1" }

        , { "Group": "GroupName2" }

    ]

}

I can allow that user into an App with this load script (as well as allow a reload task to work):

Section Access;

BasicAccess:

LOAD * INLINE [

ACCESS, GROUP, USERID,

USER, GroupName1, *

USER,  *, INTERNAL\SA_SCHEDULER

];

Section Application;

...

And from there, I can add more useful Section Access rules. Like, perhaps, making it so "GroupName2" actually has rules, or using the "OMIT" column to block accounts from seeing data from specific columns loaded in data in "Section Application", etc.  Oh, and, yes, the group name check is case-insensitive.

Alexander_Thor
Employee
Employee

My understanding is that the group information used for authorization (authZ) only exists as part of a login session; nothing is persisted

So there is two ways or providing user attributes. If you provide it during the authentication step via the API then it will be as present on user.environment and as you point out these are not persisted into QRS.

However if you have a UDC configured for the UserDirectory that you supply for the user we can then look-up additional properties for that user that will be persisted to avoid unnecessary calls to the UDC in a short period of time. Those properties are directly stored on the user entity as they are not part of the users environment

grangerats
Partner - Contributor III
Partner - Contributor III
Author

However if you have a UDC configured for the UserDirectory that you supply for the user we can then look-up additional properties for that user that will be persisted to avoid unnecessary calls to the UDC in a short period of time. Those properties are directly stored on the user entity as they are not part of the users environment

In my mind, that doesn't fit the definition of "persisted". If the data was persisted in Qlik, it would be part of the user object that is available to be manipulated via the QRS API. In my tests, the group data (that becomes available in user.environment) is not persisted into the core account information; none of it was available via .../qrs/User. (I was testing against a Windows account and had an explicit "Local network" UDC setup.)

Regardless, I'm glad I don't have to care about UDCs anymore (my custom UDC .dll had the same results as the "Local network" one). Almost all of my SSO needs are satisfied via the QPS API (Tickets)---though it would be nice if there was a way to indicate "I expect this account to already exist; please don't create one for me".