18:04, EET
December 14, 2020
Hi ,
I am using the prosys Opc Ua Java SDK for opc Ua server developement and UaExpert client with certificate/private key
authentication method.
1)I am able to establish connection between server and client
2)Validate the client certificate(add it to trusted cert store) inside onValidate(Session session, ServerUserIdentity serverUserIdentity) method.
2)I have added NodeAccessInfo in Uamodeler where Role1(Administrator) has all Permissions and Role2(SecurityAdmin) has no Permissions
I am able to get Access level of the node using getUserAccessLevel() and getAccessLevel().
I want to get Access levels for each Role i.e. Access level for Administrator Role and SecurityAdmin Role.Kindly help with a solution.
9:29, EET
Moderators
February 11, 2020
Hello,
At the moment, Roles are not supported by the OPC UA SDK for Java. See https://forum.prosysopc.com/forum/opc-ua-java-sdk/about-roles/ for previous discussion on the topic.
For now, you will have to give different users different rights based on their UserIdentity. You can do this by creating your own implementations of listeners, such as IoManagerListener and NodeManagerListener, and using ServiceContext.getSession().getUserIdentity() to get the UserIdentity and then varying the results of the method based on it.
16:55, EET
December 14, 2020
Hello Matti,
I tried using IoManagerListener and NodeManagerListener. When the client tries to access some node from the Model, I want to set AccessLevel for the client to a particular node.
For example while implementing my own IoManagerListener, I tried to read :
UaVariable node from onGetUserAccessLevel() which as per prosys documentation should be “node – The node object to read. If the node is not available this may be null.”
I wanted to check if the node corresponds to my Node name(for which I want to set Access Level) then return AccessLevelType.CurrentRead. But while debugging I noticed that the nodes’ browse names are: State,NameSpaceArray,MaxArrayLength,MaxStringLength etc.None of them corresponds to the actual node names from UaModeler .
Similarly I tried to check node Browse names from onReadValue(),onReadNonValue() in MyIOManagerListener and onBrowseNode() in MyNodeManagerListener
Below is the implementation I tried in My listener.
if (ServiceContext.getSession().getUserIdentity().getCertificate().certificate.getSubjectDN().getName().contains(“admin”)
&&
node.getBrowseName().equals(“Failure”) ){
//return some access level
}
To Sum up, Could you please clarify:
1)How to set AccessLevel for each node per client.
2)What is difference between setAccessLevel and setUserAccessLevel
3)What if 2 Clients try to access the server simultaneously, the Access level set for 1 client will be same for other client as well? What should be done to set different access level for each client trying to connect simultaneously.
Thanks
9:25, EET
Moderators
February 11, 2020
Hello,
First of all, you should NOT set different Values of AccessLevel Attribute for different Clients. That is what the UserAccessLevel Attribute is intended to be used for. The difference between AccessLevel and UserAccessLevel is that the former is used when user access rights are not considered and the latter is used when they are considered. The OPC UA specification states that UserAccessLevel can restrict restrict the accessibility indicated by the AccessLevel, but not exceed it (https://reference.opcfoundation.org/v104/Core/docs/Part3/5.6.2/). In other words, UserAccessLevel must be equal to or a subset of AccessLevel. The Prosys OPC UA SDK for Java will check both of these Attributes when checking if a Client has the right to perform an operation such as writing a Value to a Node.
Secondly, you say “When the client tries to access some node from the Model, I want to set AccessLevel for the client to a particular node”. OPC UA allows identifying both Clients and their users. Do you want the Server to set the UserAccessLevel based on the application (ApplicationIdentity) or the user of that application (UserIdentity)? If former, you can get the Client’s ApplicationIdentity with ServiceContext.getSession().getClientIdentity() and perform some comparisons with it to determine the UserAccessLevel you wish to set for this particular Client application. If latter, then use UserIdentity as adviced previously.
I would advice against setting UserAccessLevel based on the Client’s ApplicationIdentity as that would limit the access to your Server to only Clients that you have granted access in the listeners. It would also require you to provide each Client application unique ApplicationIdentity or Application Instance Certificate so that you can identify them uniquely in the Server’s code.
UaNode.getBrowseName() returns a QualifiedName object. If you compare that to a String object, their equality check will always fail. Instead, you need to use UaNode.getBrowseName().getName() to get the BrowseName as a String without its namespace index. However, since BrowseNames are not unique, I would recommend comparing NodeIds as they are unique within a Server.
Also, you might need to add null checks before attempting to get and compare the certificate of the Session to a String. Otherwise this part of the code will cause null pointer exceptions when connecting to the Server without a certificate, e.g. anonymously or with username and password. If your Server doesn’t support those type of logins, then you won’t need the checks.
If multiple Clients are connected to the Server at the same time, then listeners will be able to identify the Clients and their users based on ServiceContext as long as the one used to determine the UserAccessLevel (ApplicationIdentity or UserIdentity) is unique. In other words, as long as the solution works for a single connected Client, it will also work for multiple connected Clients as the Server will perform the checks separately for each Client.
12:38, EET
December 14, 2020
Thanks Matti.
I still have issue with accessing node( of the model) inside MyIoManagerListener.
Using UaNode.getBrowseName().getName() would get the BrowseName as a String but the Browse names are State,NameSpaceArray,MaxArrayLength,MaxStringLength etc and not the actual node names from the models.Even if I try to use NodeIds, I do not get the nodeIUd for actual nodes.
1)How to access the actual nodes(NodeIds) in MyIoManagerListener and in which method?
2)How to set user access level for particular nodes.
3)I see onGetUserAccessLevel returns Access Level Types. Are these access levels for particular node per user?
My aim is, when a client tries to access a node from model, restrict the access as per my requirement inside my own implementation of either MyIoManagerListener or MyNodeManagerListener or any other way possible.Kindly help.
14:19, EET
Moderators
February 11, 2020
Hello,
Have you added MyIoManagerListener to the IoManager of the NodeManager that manages the Nodes you wish to restrict access to? Each IoManagerListener can only see the requests related to the Nodes managed by the NodeManager containing the IoManager containing the listener. See SampleConsoleServer sample application for examples of using NodeManagers and adding listeners to them.
If you have loaded the model from a NodeSet XML-file, you can get its NodeManager with server.getAddressSpace().getNodeManager(modelURI) where server is an instance of UaServer class and modelURI is the URI of the loaded model as a String.
The access to a Node for particular users or applications can be restricted in onGetUserAccessLevel of an implementation of IoManagerListener. The method returns an AccessLevelType instance based on the Node and the ServiceContext, which contains information on both the user and the application requesting that information. You can use either of those to decide what the method should return.
16:23, EET
December 14, 2020
Thanks a lot Matti, It worked!
I was accessing the NodeManagerRoot from server and not using modelUri like below:
MyIoManagerListener im = new MyIoManagerListener();
server.getNodeManagerRoot().getIoManager().addListeners(im);
What worked for me is:
MyIoManagerListener im = new MyIoManagerListener();
server.getAddressSpace().getNodeManager(mymodelUri).getIoManager().addListeners(im);
Thanks Again for the help.
Most Users Ever Online: 1919
Currently Online:
15 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: 735
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1523
Posts: 6449
Newest Members:
rust, christamcdowall, redaahern07571, nigelbdhmp, travistimmons, AnnelCib, dalenegettinger, howardkennerley, Thomassnism, biancacraft16Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0
Administrators: admin: 1