.NET Based OPC UA Client/Server SDK
3.1.3.516
|
This example shows how to use INodeAccessInfo to set access rights to nodes and events. The class NodeAccessInfo is implementing this interface. This class allows to set distinct access rights for two particular scopes and for all other scopes together. This lesson will only use NodeAccessInfo. If your use case requires to set access rights for more than two scopes for single nodes, you can create your own class implementing the interface.
In this lesson, the access rights are set directly in code. UaModeler 1.5 will allow you set the NodeAccessInfo in the model. Please refer to the documentation of UaModeler (once it is released) for a tutorial if you prefer this way of setting the access rights.
Another possibility to assign access rights to nodes by overriding HasAccess methods that are defined at the BaseNodeManager. Please see the UaDemoServer example for a description.
Using the ImpersonateUser EventHandler you can not only control which clients are allowed connect to a server, but also enables you to add users to one or more groups, so-called scopes.
You can create a UserIdentity that will be asigned to the context of a session. This UserIdentity then contains the current scopes.
The SDK contains some well-known scopes that are defined in the WellKnownScopes enumeration. It is recommended to use these well-known scopes and extend the list if required. In this lesson, we will only use the well-known scopes Operator and Observer.
This example contains two hard coded users:
John will be added to the scopes Operator and Observer, joe only to Observer.
For being able to check access rights, we have to enable UserName tokens in the server configuration. Therefore we extend the ServerSettings in app.config:
The following code snippets can be found in the file GettingStartedServerManager.cs.
Now that we have added our users to scopes, we can set NodeAccessInfo to restrict access to nodes based on these scopes. This section shows how to do this for variables. We set the NodeAccessInfo for the variables “Temperature” and “TemperatureSetPoint”. All users shall be able to read the non-value attributes and to browse the nodes. The access to the Value attribute will be restricted.
Operators shall be able to
Observers shall be able to
Others shall only be able to read the value of TemperatureSetPoint.
If the nodes have NodeHandleType Internal or InternalPolled, there’s nothing else to implement. But our nodes are configured to have the NodeHandleType ExternalPolled. Thus, Read and Write are implemented in the NodeManager and we have to check the access permissions before returning values. We are using the HasAccess methods implemented in the BaseNodeManager to check the user’s scope against the INodeAccessInfo set for the node (see Lesson09NodeManager.cs):
To test the implementation, we connect to the server with UaExpert as anonymous user first. When selecting one of the Temperature variables, we notice in the Attributes window that we’re not allowed to read the Value attribute and the UserAccessLevel is “None”. When changing the user to “john”, the value can be read as the UserAccessLevel is now “CurrentRead, HistoryRead” (see screenshots below).
Setting the NodeAccessInfo of methods is quite similar. We will restrict the access so that only users in the scope Operator will be able to call the Controller methodes.
In this case, we only have to assign the NodeAccessInfo. The SDK perfoms all access checks. The following sample code can be found in the file Lesson09Nodemanager.NodeAccessInfo.cs
To test the implementation, we connect to the server as anonymous user and call the method stop on a controller. The method call will fail with error “BadUserAccessDenied”. After changing to user “john” we are able to successfully call the method.
INodeAccessInfo can also be used to control the access to events. In this example we will create a NodeAccessInfo and add it to the UserData of the alarm. When sending the event associated with the alarm, we assign this UserData as INodeAccessInfo to the event. The following sample code can be found in the file Lesson09NodeManager.cs.
Again, we will test the implementation using UaExpert. First we connect with UaExpert as anonymous user, create an EventView, and drag and drop the Server object to this EventView. Then we create another session with the server as user john, create another EventView, and again drag and drop the Server object to the EventView.
We now call a method being user john and compare the EventViews (see screenshots below). Both users receive the event indicating that the controller state has changed, but only john is able to receive the event associated with the alarm.