Skip to content

Commit

Permalink
[Server] ValidateRolePermissions of MonitoredItems based of the saved…
Browse files Browse the repository at this point in the history
… user identity to allow validation when no session is present (#2832)

* ValidateRolePermissions for MIs montioring the Value of a Node
* allow validation of user identity also in case of disconnected session
  • Loading branch information
romanett authored Nov 28, 2024
1 parent ed78fce commit 2f21ca8
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,18 @@ public Session Session
}
}

/// <summary>
/// The monitored items owner identity.
/// </summary>
public IUserIdentity EffectiveIdentity
{
get
{
ISubscription subscription = m_subscription;
return subscription?.EffectiveIdentity;
}
}

/// <summary>
/// The identifier for the subscription that the monitored item belongs to.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion Libraries/Opc.Ua.Server/Diagnostics/CustomNodeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3752,7 +3752,7 @@ protected virtual void OnMonitoredItemCreated(
/// <returns></returns>
public ServiceResult ValidateRolePermissions(OperationContext operationContext, NodeId nodeId, PermissionType requestedPermission)
{
if (operationContext.Session == null || requestedPermission == PermissionType.None)
if (requestedPermission == PermissionType.None)
{
// no permission is required hence the validation passes.
return StatusCodes.Good;
Expand Down
4 changes: 2 additions & 2 deletions Libraries/Opc.Ua.Server/NodeManager/MasterNodeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3233,7 +3233,7 @@ protected static ServiceResult ValidateAccessRestrictions(OperationContext conte
/// <returns></returns>
protected internal static ServiceResult ValidateRolePermissions(OperationContext context, NodeMetadata nodeMetadata, PermissionType requestedPermission)
{
if (context.Session == null || nodeMetadata == null || requestedPermission == PermissionType.None)
if (nodeMetadata == null || requestedPermission == PermissionType.None)
{
// no permission is required hence the validation passes
return StatusCodes.Good;
Expand Down Expand Up @@ -3323,7 +3323,7 @@ protected internal static ServiceResult ValidateRolePermissions(OperationContext
}
}

var currentRoleIds = context.Session.Identity.GrantedRoleIds;
var currentRoleIds = context.UserIdentity.GrantedRoleIds;
if (currentRoleIds == null || currentRoleIds.Count == 0)
{
return ServiceResult.Create(StatusCodes.BadUserAccessDenied, "Current user has no granted role.");
Expand Down
1 change: 1 addition & 0 deletions Libraries/Opc.Ua.Server/Server/OperationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ public OperationContext(IMonitoredItem monitoredItem)
if (monitoredItem == null) throw new ArgumentNullException(nameof(monitoredItem));

m_channelContext = null;
m_identity = monitoredItem.EffectiveIdentity;
m_session = monitoredItem.Session;

if (m_session != null)
Expand Down
5 changes: 5 additions & 0 deletions Libraries/Opc.Ua.Server/Subscription/IMonitoredItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public interface IMonitoredItem
/// </summary>
Session Session { get; }

/// <summary>
/// The monitored items owner identity.
/// </summary>
IUserIdentity EffectiveIdentity { get; }

/// <summary>
/// The identifier for the item that is unique within the server.
/// </summary>
Expand Down
13 changes: 13 additions & 0 deletions Libraries/Opc.Ua.Server/Subscription/MonitoredItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,19 @@ public Session Session
}
}
}
/// <summary>
/// The monitored items owner identity.
/// </summary>
public IUserIdentity EffectiveIdentity
{
get
{
lock (m_lock)
{
return m_subscription?.EffectiveIdentity;
}
}
}

/// <summary>
/// The identifier for the item that is unique within the server.
Expand Down
25 changes: 15 additions & 10 deletions Libraries/Opc.Ua.Server/Subscription/Subscription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public interface ISubscription
/// </summary>
Session Session { get; }

/// <summary>
/// The subscriptions owner identity.
/// </summary>
IUserIdentity EffectiveIdentity { get; }

/// <summary>
/// The identifier for the item that is unique within the server.
/// </summary>
Expand Down Expand Up @@ -208,6 +213,14 @@ public uint Id
get { return m_id; }
}

/// <summary>
/// The subscriptions owner identity.
/// </summary>
public IUserIdentity EffectiveIdentity
{
get { return (m_session != null) ? m_session.EffectiveIdentity : m_savedOwnerIdentity; }
}

/// <summary>
/// Queues an item that is ready to publish.
/// </summary>
Expand Down Expand Up @@ -255,14 +268,6 @@ public NodeId SessionId
}
}

/// <summary>
/// The owner identity.
/// </summary>
public UserIdentityToken OwnerIdentity
{
get { return (m_session != null) ? m_session.IdentityToken : m_savedOwnerIdentity; }
}

/// <summary>
/// Gets the lock that must be acquired before accessing the contents of the Diagnostics property.
/// </summary>
Expand Down Expand Up @@ -594,7 +599,7 @@ public void SessionClosed()
{
if (m_session != null)
{
m_savedOwnerIdentity = m_session.IdentityToken;
m_savedOwnerIdentity = m_session.EffectiveIdentity;
m_session = null;
}
}
Expand Down Expand Up @@ -2414,7 +2419,7 @@ private void TraceState(LogLevel logLevel, TraceStateId id, string context)
private IServerInternal m_server;
private Session m_session;
private uint m_id;
private UserIdentityToken m_savedOwnerIdentity;
private IUserIdentity m_savedOwnerIdentity;
private double m_publishingInterval;
private uint m_maxLifetimeCount;
private uint m_maxKeepAliveCount;
Expand Down
4 changes: 2 additions & 2 deletions Libraries/Opc.Ua.Server/Subscription/SubscriptionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,11 +1223,11 @@ public void TransferSubscriptions(
}

// get the identity of the current or last owner
UserIdentityToken ownerIdentity = subscription.OwnerIdentity;
UserIdentityToken ownerIdentity = subscription.EffectiveIdentity.GetIdentityToken();

// Validate the identity of the user who owns/owned the subscription
// is the same as the new owner.
bool validIdentity = Utils.IsEqualUserIdentity(ownerIdentity, context.Session.IdentityToken);
bool validIdentity = Utils.IsEqualUserIdentity(ownerIdentity, context.Session.EffectiveIdentity.GetIdentityToken());

// Test if anonymous user is using a
// secure session using Sign or SignAndEncrypt
Expand Down

0 comments on commit 2f21ca8

Please sign in to comment.