10:48, EEST
May 19, 2020
Hi,
I’ve already implemented some kind of permission handling on our Prosys OPC UA Server depending on the logged-in user wich is working great so far. Now I’m wondering how to bring roles into play. I know that the standard supports roles (RoleType) and that you should see them in the address space, but oviously I’m no OPC UA expert jet.
Ist there the possibility to implement a role model with the Java SDK compliant to the standard and utilize the RolePermissions, UserRolePermissions and AccessRestrictions attributes of each Node? If I connect with UA Browser, those attributes are shown with a Bad_AttributeIdInvalid exception. How would you suggest handling roles in general?
Thanks!
Greetings,
Christopher
12:41, EEST
April 3, 2012
Hi,
I think you are the first to ask this, good question.
Those (Roles, as a concept) were added in OPC UA Specification version 1.04, thus they are relatively new things.
In practice we do not have support for them in the Server side at all.
For the Client side we do read them for UaNode objects, though you will need to use the raw id based API UaNode.readAttribute(UnsignedInteger attributeId) (pass Attributes.RolePermissions for example to it) to get the values of those Attributes (or use UaClient.readXXX methods).
It might be possible to implement them in the server side with IoManagerListeners to handle the new attributes, but you would need to handle the validation of the roles yourself manually. Most places of the SDK does accept have a Listener of sorts which has the ServiceContext as a parameter that can be used to determine the Session/User which made the service call. I would expect it to be somewhat complicated, so preferably we should have some real support for this in the future. Also I’m not sure there is a listener to every possible operation the role system might define.
Since our SDK has existed since the start of OPC UA, it is non-trivial to “glue on” the role system, that was introduced this late so to say to the specification. It should be baked close to the “core”, in my personal opinion. Given that we have had our hands full in other requested features (such as PubSub, which will still continue to take larger than I would like chunk of dev time), we have not yet looked towards the new Attributes (other than the DataTypeDefinition, which had immediate uses).
For the Application layer, i.e. application made using the SDK, but not the SDK code itself, I would look for an existing de-facto standard library that can be used to evaluate roles and use that. Thus maybe something from the answers of: https://stackoverflow.com/questions/3895467/role-based-access-control, though they might be more web-related.
For SDK code, I’m not yet sure how we would implement this. At minimum we could/should add the Attributes to the server side UaNode implementations, though at with UserRolePermissions we would probably want to avoid the same thing that happened with other UserXXX Attributes. On the Client side it makes sense, but on the server side given that it is Session/User based, it really cannot be stored in the UaNodes (and having API to access it from that would also not make sense, though we have tried our best to have the UaNode to be a common client and server side API, so it is a bit … mess). At least in general we try to avoid having too many dependencies, so lets see how it goes in the future (adding the Attributes to do the nodes without also adding the backing functionality would not be a good idea in my opinion).
How critical this these features would be for you in the Server side?
And as extra clarification, most places do have a Listener that can be used for user authorization checks, just that given that those were made before OPC UA 1.04 era, we do not have specific support for the new role Attributes, but most of the authorization checks can be still made.
I think it might be closer to like SDK 5.x, if we could revamp some core parts of the SDK to accommodate these better. Though we also just cannot like rewrite everything (too much work and backwards-compatibility would suffer). I think in 2021 there will be OPC UA 1.05 (or late this year, I do not know exactly when), so given the current trend we would most likely jump major version then (we have done so previously on 1.02, 1.03, 1.04) so we could do probably some a bit larger updates then.
P.S.
Regardless, at least one part of PubSub does depend on the Roles, so eventually through that the very least they will be implemented in one form or another.
13:47, EEST
May 19, 2020
Hello Bjarne,
thanks for your reply. I can see that the OPC UA role model is quite comprehensive with lots of dependencies regarding node and io management. For now, a lightweight custom solution on the Application layer will do for us I guess.
Regarding the display of Attribute exceptions in UA Browser: Maybe you could change the way those are displayed for optional attributes (bright red suggests something is critically wrong).
9:05, EEST
November 3, 2021
Hello,
I’ve added a NodeManagerListener to my Node Manager instance and I’m trying to access the RolePermissions attribute within NodeManagerListener::onBrowseNode method. I have tried using the UaNode.readAttribute(UnsignedInteger attributeId) method to retrieve the value. However, I get the following error –> Bad_AttributeIdInvalid (0x80350000) “The attribute is not supported for the specified Node.” Is there any other way to read the RolePermissions attribute?
Thanks in advance
11:05, EEST
April 3, 2012
Hi,
Sorry, but in practice the situation regrading Roles is the same as in the above post from me from 2020. This is to say, no support in the server side. In the client the raw value can be read for visualization purposes, but e.g. the client doesn’t yet use those values in it’s internal logic. Thus, the UaNode.readAttribute (as I mentioned) for those would only work on the client side.
Technically you might be able to “inject visually” the value for those Attributes in the server side via an IoManagerListener from outside of the nodes, e.g.
@Override public boolean onReadNonValue(ServiceContext serviceContext, NodeId nodeId, UaNode node, UnsignedInteger attributeId, DataValue dataValue) throws StatusException { if (Attributes.UserRolePermissions.equals(attributeId)) { dataValue.setValue(new Variant(new RolePermissionType[] {new RolePermissionType(roleNodeId, PermissionType.Browse)})); dataValue.setStatusCode(StatusCode.GOOD); return true; } return false; }
(setting the status to good is important, as the default at this point is Bad_AttributeIdInvalid as the node doesn’t have a value. This error code in OPC UA means both that the node doesn’t have an initial value OR it is not supported at all for the node; this can be confusing).
However, IMPORTANT!, it should be noted that this is not tested nor supported i.e. the SDK is not aware of the value you give here i.e. you would need to do all the behind work for clients to actually be able to use it (or basically meaning nothing is restricted by the SDK if you just return this value, you would need to do that manually via probably a lots of listeners to things). But technically clients should like see this value you give.
11:29, EEST
November 3, 2021
Hi Bjarne,
Thank you for your reply. My current requirement is only to read the permissions set for the node and compare it against the permissions the client has in order to restrict access. I was looking for ways to read it from the RolePermissions attribute, hence the query; maybe I will add the RolePermissions value to the Description attribute instead and match them against some regex to retrieve the values. For now, that seems like the only viable option.
13:48, EEST
April 3, 2012
I would not recommend doing that, if possible, as it would not be interoperable with other clients.
Also specifically for UserRolePermissions, the value should be provided by a listener anyway. We have made a mistake in the past by having “storage” for UserXXX Attributes, but having a single value in a node is not very useful, when it should be depending on the Session/User who connected. Thus for those the current proper way is via IoManagerListener.onGetUserXXX and returning value based on the ServiceContext (you can get the session/user from it). So once we would be supporting UserRolePermissions, most likely we would not repeat the mistake i.e. “entering” a value via the listener would be the only way and the node itself would not contain a field for it.
Thus, please try the above post code first.
P.S. Also while testing the code, we did notice the our Browser application has problems decoding structures with “OptionSet” Datatypes, it is application-related, the SampleConsoleClient of the SDK can read it just fine.
18:52, EEST
September 11, 2024
Hello Bjarne,
It has been nearly 2 years since this thread became dormant. I just wanted to clarify a few things and see if anything has changed.
I am trying to implement an OPCUA server using the SDK. I have a role based authentication mechanism in my application system, that I use to authorize user access to appropriate actions on particular nodes using the IoManagerListener and the NodeManagerListener.
However, I am facing the same issue as users above, of seeing the following attributes in OPC UA Browser in red:
– RolePermissions
– UserRolePermissions
– AccessRestrictions
– AccessLevel
– AccessLevelEx
with the value: Bad_AttributeIdInvalid (0x80350000) “The attribute is not supported for the specified Node.”
Questions:
1. How do I set (or rather inject visually) the values to the correct values for the user based on their access? What would these correct values be?
2. In the quoted example you provided, the RolePermissionType constructor takes a NodeId roleNodeId parameter. How do I get the RoleId for a particular OPCUA Role?
3. Maybe a more primitive question would be, how would I go about merging my application’s role system to the OPCUA Role system? As the protocol defines a set of well-known roles to be implemented by the server – https://reference.opcfoundation.org/Core/Part3/v104/docs/4.8.2#Table%202 , any thoughts on how to correspond these roles to roles in my application would be deeply appreciated.
4. The protocol specifies that if the server supports permissions (which my server does), we have to specify the ” property on the Namespace. https://reference.opcfoundation.org/Core/Part3/v104/docs/5.2.9#:~:text=If%20a%20Server%20supports%20Permissions%20for%20a%20particular%20Namespace%20it%20shall%20add%20the%20DefaultRolePermissions%20Property%20to%20the%20NamespaceMetadata%20Object%20for%20that%20Namespace
Is there a way to do this in the java SDK?
Thank you so much!
Bjarne Boström said
Hi,Sorry, but in practice the situation regrading Roles is the same as in the above post from me from 2020. This is to say, no support in the server side. In the client the raw value can be read for visualization purposes, but e.g. the client doesn’t yet use those values in it’s internal logic. Thus, the UaNode.readAttribute (as I mentioned) for those would only work on the client side.
Technically you might be able to “inject visually” the value for those Attributes in the server side via an IoManagerListener from outside of the nodes, e.g.
@Override public boolean onReadNonValue(ServiceContext serviceContext, NodeId nodeId, UaNode node, UnsignedInteger attributeId, DataValue dataValue) throws StatusException { if (Attributes.UserRolePermissions.equals(attributeId)) { dataValue.setValue(new Variant(new RolePermissionType[] {new RolePermissionType(roleNodeId, PermissionType.Browse)})); dataValue.setStatusCode(StatusCode.GOOD); return true; } return false; }(setting the status to good is important, as the default at this point is Bad_AttributeIdInvalid as the node doesn’t have a value. This error code in OPC UA means both that the node doesn’t have an initial value OR it is not supported at all for the node; this can be confusing).
However, IMPORTANT!, it should be noted that this is not tested nor supported i.e. the SDK is not aware of the value you give here i.e. you would need to do all the behind work for clients to actually be able to use it (or basically meaning nothing is restricted by the SDK if you just return this value, you would need to do that manually via probably a lots of listeners to things). But technically clients should like see this value you give.
Most Users Ever Online: 1919
Currently Online:
53 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 734
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1523
Posts: 6449
Newest Members:
christamcdowall, redaahern07571, nigelbdhmp, travistimmons, AnnelCib, dalenegettinger, howardkennerley, Thomassnism, biancacraft16, edgardo3518Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0
Administrators: admin: 1