In the permission authorization step, the security roles of the user are checked to verify that the user is granted the necessary permission to perform the operation on the given entity. If the user’s role includes the required permissions for the requested action, access is granted; otherwise, it is denied.
OPC Wizard allows the developer to specify permission assignment on every custom server node. The permission assignment specifies the permissions granted to individual roles. In addition, permissions can be inherited from the parent node or from the default for the namespace. If you have special needs, the permission checking mechanism can also be customized in the code.
Permissions define the actions allowed on resources (entities). In OPC Wizard, permissions are specified using the UAPermissions Enumeration. Flags from this enumeration can be combined together. Following are the individual OPC UA permissions defined by the enumeration:
| Member | Value | Description |
|---|---|---|
| AddNode | 65536 | Add node. |
| AddReference | 8192 | Add reference. |
| Browse | 1 | Browse. |
| Call | 4096 | Call. |
| DeleteHistory | 1024 | Delete history. |
| DeleteNode | 32768 | Delete node. |
| InsertHistory | 256 | Insert history. |
| None | 0 | None. |
| Read | 32 | Read. |
| ReadHistory | 128 | Read history. |
| ReadRolePermissions | 2 | Read role permissions. |
| ReceiveEvents | 2048 | Receive events. |
| RemoveReference | 16384 | Remove reference. |
| Write | 64 | Write. |
| WriteAttribute | 4 | Write attribute. |
| WriteHistorizing | 16 | Write historizing. |
| WriteRolePermissions | 8 | Write role permissions. |
OPC Wizard also predefines some useful combinations:
| Member | Value | Description |
|---|---|---|
| All | -1 | All permissions. |
| EditHistory | 1792 | Permissions for editing history (insert, modify, and delete). |
| ModifyAll | 128860 | All modification permissions including attributes, role permissions, historizing, value writes, history editing, calls, references, and node operations. |
| ModifyBasic | 4160 | Basic modification permissions (write values and call methods). |
| ModifyRegular | 4180 | Regular modification permissions including attributes, historizing, value writes, and method calls. |
| ModifySecurity | 4172 | Security-related modification permissions including attributes, role permissions, value writes, and method calls. |
| ViewAll | 2211 | All viewing permissions including browse, role permissions, value reads, history reads, and event reception. |
| ViewBasic | 33 | Basic viewing permissions (browse and read values). |
| ViewRegular | 2209 | Regular viewing permissions including browse, value reads, history reads, and event reception. |
| ViewSecurity | 35 | Security-related viewing permissions including browse, value reads, and role permissions. |
The permission assignment defines which permissions are actually granted by specific security roles. In OPC Wizard, role assignment is represented by an instance of UAPermissionAssignment Class. This object is a collection of UARolePermissions object, each of which contains a role ID and the corresponding permissions, represented by flags from UAPermissions Enumeration. The UAPermissionAssignment Class is a keyed collection where the key is the role ID. For a user that is in some security roles (given by their role IDs), his permissions given by the permission assignment will be a union of the permissions in the role assignment for the security roles the user is in.
You can construct the permission assignments in the code yourself, or you can use one of the predefined permission assignments, available as static properties on the UAPermissionAssignment Class:
| Name | Description | |
|---|---|---|
![]() ![]() |
AuthenticateUserToModify | Permission assignment that allows anonymous users to view and authenticated users to view and modify. |
![]() ![]() |
Empty | An empty permission assignment with no role permissions. |
![]() ![]() |
EveryoneFullAccess | Permission assignment that gives full access to everyone (anonymous users). |
![]() ![]() |
RoleBasis | Permission assignment based on the standard OPC UA roles with their base permissions. |
![]() ![]() |
TrustApplicationToModify | Permission assignment that allows anonymous users to view and trusted applications to view and modify. |
Each custom server node (represented by an instance of UAServerNode Class) has a PermissionAssignment Property which can be used to control access to the node and operations on the node. This property contains a UAPermissionAssignment object described above. By confuring this property, you define the type of access the users with various roles will have to the node.
OPC Wizard takes care of checking whether the user performing any operation has the necessary permission. If the user does not have the permission, the operation is automatically rejected by the OPC Wizard, without further need for coding on your side - all that's needed is to configure the right permission assignments.
For custom nodes under the Objects folder, the default value of PermissionAssignment Property is Empty. This does not mean, however, that such server nodes will not be accessible at all, because OPC Wizard combines this explicitly defined property assignment with an inherited one - see further below.
The OPC Wizard evaluates whether the user has the necessary permission using the effective permission assignment. The effective permission assignment on a server node is calculated by combining (making a union of) the explicitly defined permission assignments on the node (the PermissionAssignment Property) with base permission assignment. This mechanisms allows the permission assignment be inherited from the namespace or the parent node, making it easier to define permissions on larger node hierarchies.
The base permission assignment, i.e. what is inherited, depends on the setting of the PermissionsInheritanceType Property on the server node, and can be one of the following:
| Member | Value | Description |
|---|---|---|
| Namespace | 1 | Permissions are inherited from the namespace. |
| None | 0 | No permission inheritance. The node uses only its own permission assignment. |
| ParentNode | 2 | Permissions are inherited from the parent node. This is the default inheritance type. |
The default permissions inheritance type for custom nodes under the Objects folder is ParentNode. The Objects node itself, however, has its permissions inheritance type set to Namespace by default.
For server nodes defined in the Objects folder hierarchy, "Inheriting from the namespace" means that the base permission assignment is taken from the ObjectsNamespaceDefaultPermissionAssignment Property on the EasyUAServer object.
Your code can make use of these defaults e.g. in following ways:
Simply changing the ObjectsNamespaceDefaultPermissionAssignment Property assigns the specified permission to all custom nodes in the Objects folder hierarchy that have not defined a different permisssions inheritance type.
Changing the PermissionAssignment Property on any node in the Objects folder hierarchy defines the permission assignment for this node, and also for all its children, recursively (all descendants), unless the permissions inheritance type has been changed on the descendant.
Permisssion assignment, including inheritance, is illustrated in the example below.
In advanced scenarios, you can complement the permission authorization behavior described above and implement your own authorization logic. To allow for this, OPC Wizard passes a server operation context (an instance of the UAServerOperationContext Class) to the method events used to implement OPC operations such as reads, writes, and subscriptions. Inside the server operation context, you will find a SecurityPrincipal Property. This security principal encapsulated the identity and role-based security information related to the operation, and allows your code to make security-based decisions. Specifically, among other things, you can
The custom logic to perform permission authorization can be placed to:
If your code determines that the permission should be granted, continue to the base implementation of the method, or do not handle the event. Otherwise, fail the operation with appropriate status code, in most cases BadUserAccessDenied.
Even when you implement the custom permission authorization, the OPC Wizard's built-in mechanism still remains in effect. Consequently, your authorization logic can only deny access where the built-in mechanism has already granted access. But your authorization logic cannot grant access where the built-in mechanism has already denied it. Your custom logic can make the permissions narrower, not wider. Make sure you define "wide enough" permissions using the built-in permission authorization mechanism, so that your custom logic gets a chance to run and in cases it is supposed to act upon.