This is an automated email from the ASF dual-hosted git repository.

petrov-mg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new b1cc16f74cb IGNITE-28753 Replaced dedicated Security Context 
propagation with common distributed Operation Context (#13313)
b1cc16f74cb is described below

commit b1cc16f74cb084a31a0de5ca20e9d1c7b9d2ed03
Author: Vladimir Steshin <[email protected]>
AuthorDate: Fri Jul 3 16:05:14 2026 +0300

    IGNITE-28753 Replaced dedicated Security Context propagation with common 
distributed Operation Context (#13313)
---
 .../ignite/internal/CoreMessagesProvider.java      | 10 ++--
 .../managers/communication/GridIoManager.java      | 58 +++++++-----------
 .../communication/GridIoSecurityAwareMessage.java  | 68 ----------------------
 .../managers/discovery/GridDiscoveryManager.java   |  6 +-
 .../IgniteAuthenticationProcessor.java             |  2 +-
 .../security/IgniteSecurityProcessor.java          | 65 +++++++++++++--------
 .../security/SecurityContextWrapper.java           | 61 +++++++++++++++++++
 .../DistributedOperationContextAttribute.java      | 36 ++++++++++++
 .../thread/context/OperationContextDispatcher.java |  1 +
 .../main/resources/META-INF/classnames.properties  |  1 -
 .../security/IgniteSecurityProcessorTest.java      | 30 +++-------
 .../context/OperationContextAttributesTest.java    |  8 ++-
 12 files changed, 185 insertions(+), 161 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
index 1af6f8945cf..e037bd50f02 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
@@ -28,7 +28,6 @@ import 
org.apache.ignite.internal.managers.checkpoint.GridCheckpointRequest;
 import org.apache.ignite.internal.managers.communication.CompressedMessage;
 import org.apache.ignite.internal.managers.communication.ErrorMessage;
 import org.apache.ignite.internal.managers.communication.GridIoMessage;
-import 
org.apache.ignite.internal.managers.communication.GridIoSecurityAwareMessage;
 import org.apache.ignite.internal.managers.communication.GridIoUserMessage;
 import org.apache.ignite.internal.managers.communication.IgniteIoTestMessage;
 import org.apache.ignite.internal.managers.communication.SessionChannelMessage;
@@ -240,6 +239,7 @@ import 
org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultRe
 import 
org.apache.ignite.internal.processors.rollingupgrade.RollingUpgradeNodeData;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteFeatureSet;
 import 
org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteProductFeatures;
+import org.apache.ignite.internal.processors.security.SecurityContextWrapper;
 import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest;
 import 
org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult;
 import 
org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResultBatch;
@@ -608,12 +608,13 @@ public class CoreMessagesProvider extends 
AbstractMarshallableMessageFactoryProv
         // [11500 - 11600]:  IO, networking messages.
         msgIdx = NODE_ID_MSG_TYPE;
         withNoSchema(NodeIdMessage.class);
+        msgIdx = HANDSHAKE_MSG_TYPE;
         withNoSchema(HandshakeMessage.class);
+        msgIdx = HANDSHAKE_WAIT_MSG_TYPE;
         withNoSchema(HandshakeWaitMessage.class);
         withNoSchema(GridIoMessage.class);
         withNoSchema(IgniteIoTestMessage.class);
         withSchema(GridIoUserMessage.class);
-        withSchema(GridIoSecurityAwareMessage.class);
         withNoSchema(RecoveryLastReceivedMessage.class);
         withNoSchema(TcpInverseConnectionResponseMessage.class);
         withNoSchema(SessionChannelMessage.class);
@@ -690,9 +691,10 @@ public class CoreMessagesProvider extends 
AbstractMarshallableMessageFactoryProv
         // [13400 - 13500]: Operation context messages.
         msgIdx = 13400;
         withNoSchema(OperationContextMessage.class);
+        withNoSchema(SecurityContextWrapper.class);
 
-        // [13500 - 13600]: Rolling Upgrade messages.
-        msgIdx = 13500;
+        // [13600 - 13700]: Rolling Upgrade messages.
+        msgIdx = 13600;
         withNoSchema(IgniteFeatureSet.class);
         withNoSchema(IgniteProductFeatures.class);
         withNoSchema(RollingUpgradeNodeData.class);
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index a83e6ae8e7d..08befbe2500 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@ -137,7 +137,6 @@ import 
org.apache.ignite.spi.communication.tcp.internal.CommunicationListenerEx;
 import org.apache.ignite.spi.communication.tcp.internal.ConnectionRequestor;
 import 
org.apache.ignite.spi.communication.tcp.internal.TcpConnectionRequestDiscoveryMessage;
 import 
org.apache.ignite.spi.communication.tcp.internal.TcpInverseConnectionResponseMessage;
-import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
@@ -1317,7 +1316,7 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
 
                     assert obj != null;
 
-                    invokeListener(msg.policy(), lsnr, nodeId, obj, 
secSubjId(msg));
+                    invokeListener(msg.policy(), lsnr, nodeId, obj);
                 }
                 finally {
                     threadProcessingMessage(false, null);
@@ -1455,7 +1454,7 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
 
         assert obj != null;
 
-        invokeListener(msg.policy(), lsnr, nodeId, obj, secSubjId(msg));
+        invokeListener(msg.policy(), lsnr, nodeId, obj);
     }
 
     /**
@@ -1819,9 +1818,8 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
      * @param lsnr Listener.
      * @param nodeId Node ID.
      * @param msg Message.
-     * @param secSubjId Security subject that will be used to open a security 
session.
      */
-    private void invokeListener(Byte plc, GridMessageListener lsnr, UUID 
nodeId, Object msg, UUID secSubjId) {
+    private void invokeListener(Byte plc, GridMessageListener lsnr, UUID 
nodeId, Object msg) {
         MTC.span().addLog(() -> "Invoke listener");
 
         Byte oldPlc = CUR_PLC.get();
@@ -1831,9 +1829,7 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
         if (change)
             CUR_PLC.set(plc);
 
-        UUID newSecSubjId = secSubjId != null ? secSubjId : nodeId;
-
-        try (Scope ignored = ctx.security().withContext(newSecSubjId)) {
+        try (Scope ignored = withRemoteSecurityContext(nodeId)) {
             lsnr.onMessage(nodeId, msg, plc);
         }
         finally {
@@ -1842,6 +1838,19 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
         }
     }
 
+    /** */
+    private Scope withRemoteSecurityContext(UUID nodeId) {
+        // No remote Security Context has been attached to the message 
processing thread so far.
+        // This means that the message was sent as part of an operation 
initiated by the sender node.
+        if (ctx.security().isDefaultContext())
+            return ctx.security().withContext(nodeId);
+
+        // Verify that the Security Context currently attached to the thread 
is valid.
+        ctx.security().securityContext();
+
+        return Scope.NOOP_SCOPE;
+    }
+
     /**
      * @return Current IO policy
      */
@@ -2029,11 +2038,8 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
         return ctx.config().getFailureDetectionTimeout();
     }
 
-    /**
-     * @return One of two message wrappers. The first is {@link 
GridIoMessage}, the second is secured version {@link
-     * GridIoSecurityAwareMessage}.
-     */
-    private @NotNull GridIoMessage createGridIoMessage(
+    /** @return A {@link GridIoMessage} wrapper for {@code msg}. */
+    public GridIoMessage createGridIoMessage(
         Object topic,
         Message msg,
         byte plc,
@@ -2043,16 +2049,7 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
     ) {
         GridIoMessage res;
 
-        if (ctx.security().enabled()) {
-            UUID secSubjId = null;
-
-            if (!ctx.security().isDefaultContext())
-                secSubjId = ctx.security().securityContext().subject().id();
-
-            res = new GridIoSecurityAwareMessage(secSubjId, plc, topic, msg, 
ordered, timeout, skipOnTimeout);
-        }
-        else
-            res = new GridIoMessage(plc, topic, msg, ordered, timeout, 
skipOnTimeout);
+        res = new GridIoMessage(plc, topic, msg, ordered, timeout, 
skipOnTimeout);
 
         res.opCtxMsg = 
ctx.operationContextDispatcher().collectDistributedAttributes();
 
@@ -3812,7 +3809,7 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
 
                         MTC.span().addTag(SpanTags.MESSAGE, () -> 
traceName(fmc.message));
 
-                        invokeListener(plc, lsnr, nodeId, 
mc.message.message(), secSubjId(mc.message));
+                        invokeListener(plc, lsnr, nodeId, 
mc.message.message());
                     }
                     finally {
                         if (mc.closure != null)
@@ -4241,19 +4238,6 @@ public class GridIoManager extends 
GridManagerAdapter<CommunicationSpi<Object>>
         }
     }
 
-    /**
-     * @return Security subject id.
-     */
-    private UUID secSubjId(GridIoMessage msg) {
-        if (ctx.security().enabled()) {
-            assert msg instanceof GridIoSecurityAwareMessage;
-
-            return ((GridIoSecurityAwareMessage)msg).securitySubjectId();
-        }
-
-        return null;
-    }
-
     /**
      * Responsible for handling network situation where server cannot open 
connection to client and
      * has to ask client to establish a connection to specific server.
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoSecurityAwareMessage.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoSecurityAwareMessage.java
deleted file mode 100644
index d1a6040d3d6..00000000000
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoSecurityAwareMessage.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.managers.communication;
-
-import java.util.UUID;
-import org.apache.ignite.internal.Order;
-import org.apache.ignite.plugin.extensions.communication.Message;
-
-/**
- *
- */
-public class GridIoSecurityAwareMessage extends GridIoMessage {
-    /** Security subject ID that will be used during message processing on a 
remote node. */
-    @Order(0)
-    UUID secSubjId;
-
-    /**
-     * Default constructor.
-     */
-    public GridIoSecurityAwareMessage() {
-        // No-op.
-    }
-
-    /**
-     * @param secSubjId Security subject ID.
-     * @param plc Policy.
-     * @param topic Communication topic.
-     * @param msg Message.
-     * @param ordered Message ordered flag.
-     * @param timeout Timeout.
-     * @param skipOnTimeout Whether message can be skipped on timeout.
-     */
-    public GridIoSecurityAwareMessage(
-        UUID secSubjId,
-        byte plc,
-        Object topic,
-        Message msg,
-        boolean ordered,
-        long timeout,
-        boolean skipOnTimeout
-    ) {
-        super(plc, topic, msg, ordered, timeout, skipOnTimeout);
-
-        this.secSubjId = secSubjId;
-    }
-
-    /**
-     * @return Security subject ID.
-     */
-    UUID securitySubjectId() {
-        return secSubjId;
-    }
-}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
index d7a599271f0..7411e501b3c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
@@ -226,7 +226,7 @@ public class GridDiscoveryManager extends 
GridManagerAdapter<DiscoverySpi> {
     };
 
     /** Discovery cached history size. */
-    private final int DISCOVERY_HISTORY_SIZE = 
getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, DFLT_DISCOVERY_HISTORY_SIZE);
+    private final int discoHistSz = getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, 
DFLT_DISCOVERY_HISTORY_SIZE);
 
     /** */
     private final Object discoEvtMux = new Object();
@@ -254,7 +254,7 @@ public class GridDiscoveryManager extends 
GridManagerAdapter<DiscoverySpi> {
 
     /** Topology cache history. */
     private final GridBoundedConcurrentLinkedHashMap<AffinityTopologyVersion, 
DiscoCache> discoCacheHist =
-        new GridBoundedConcurrentLinkedHashMap<>(DISCOVERY_HISTORY_SIZE);
+        new GridBoundedConcurrentLinkedHashMap<>(discoHistSz);
 
     /** Topology snapshots history. */
     private volatile NavigableMap<Long, Collection<ClusterNode>> topHist = 
Collections.emptyNavigableMap();
@@ -1107,7 +1107,7 @@ public class GridDiscoveryManager extends 
GridManagerAdapter<DiscoverySpi> {
 
             rcvdCustomMsgs.addLast(customMsg.id());
 
-            while (rcvdCustomMsgs.size() > DISCOVERY_HISTORY_SIZE)
+            while (rcvdCustomMsgs.size() > discoHistSz)
                 rcvdCustomMsgs.pollFirst();
         }
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
index 55a5c22f2a8..74a7dca34a8 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java
@@ -1302,7 +1302,7 @@ public class IgniteAuthenticationProcessor extends 
GridProcessorAdapter implemen
         }
 
         /** {@inheritDoc} */
-        @Override protected void body() throws InterruptedException, 
IgniteInterruptedCheckedException {
+        @Override protected void body() {
             if (ctx.clientNode())
                 return;
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java
index 7b34ed75db2..ddbf0d3d96f 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java
@@ -34,6 +34,7 @@ import 
org.apache.ignite.internal.processors.security.sandbox.IgniteSandbox;
 import org.apache.ignite.internal.processors.security.sandbox.NoOpSandbox;
 import org.apache.ignite.internal.thread.context.OperationContext;
 import org.apache.ignite.internal.thread.context.OperationContextAttribute;
+import org.apache.ignite.internal.thread.context.OperationContextDispatcher;
 import org.apache.ignite.internal.thread.context.Scope;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -55,6 +56,7 @@ import static 
org.apache.ignite.internal.processors.security.SecurityUtils.IGNIT
 import static 
org.apache.ignite.internal.processors.security.SecurityUtils.MSG_SEC_PROC_CLS_IS_INVALID;
 import static 
org.apache.ignite.internal.processors.security.SecurityUtils.hasSecurityManager;
 import static 
org.apache.ignite.internal.processors.security.SecurityUtils.nodeSecurityContext;
+import static 
org.apache.ignite.internal.thread.context.DistributedOperationContextAttribute.SECURITY;
 import static 
org.apache.ignite.plugin.security.SecurityPermission.ADMIN_USER_ACCESS;
 import static 
org.apache.ignite.plugin.security.SecurityPermission.JOIN_AS_SERVER;
 
@@ -88,8 +90,12 @@ public class IgniteSecurityProcessor extends 
IgniteSecurityAdapter {
         return SANDBOXED_NODES_COUNTER.get() > 0;
     }
 
-    /** Context attribute that holds Security Context. */
-    private static final OperationContextAttribute<SecurityContext> SEC_CTX = 
OperationContextAttribute.newInstance();
+    /**
+     * Attribute that holds local and distributed Security Context.
+     *
+     * @see OperationContextDispatcher
+     */
+    private static final OperationContextAttribute<SecurityContextWrapper> 
SEC_CTX_ATTR = OperationContextAttribute.newInstance();
 
     /** Security processor. */
     private final GridSecurityProcessor secPrc;
@@ -126,28 +132,12 @@ public class IgniteSecurityProcessor extends 
IgniteSecurityAdapter {
 
     /** {@inheritDoc} */
     @Override public Scope withContext(SecurityContext secCtx) {
-        return OperationContext.set(SEC_CTX, secCtx == dfltSecCtx ? null : 
secCtx);
+        return OperationContext.set(SEC_CTX_ATTR, secCtx == dfltSecCtx ? null 
: new SecurityContextWrapper(secCtx));
     }
 
     /** {@inheritDoc} */
     @Override public Scope withContext(UUID subjId) {
-        try {
-            SecurityContext res = secPrc.securityContext(subjId);
-
-            if (res == null) {
-                res = findNodeSecurityContext(subjId);
-
-                if (res == null)
-                    throw new IllegalStateException("Failed to find security 
context for subject with given ID : " + subjId);
-            }
-
-            return withContext(res);
-        }
-        catch (Throwable e) {
-            log.error(FAILED_OBTAIN_SEC_CTX_MSG, e);
-
-            throw e;
-        }
+        return withContext(securityContext(subjId));
     }
 
     /**
@@ -172,14 +162,41 @@ public class IgniteSecurityProcessor extends 
IgniteSecurityAdapter {
 
     /** {@inheritDoc} */
     @Override public boolean isDefaultContext() {
-        return OperationContext.get(SEC_CTX) == null;
+        return OperationContext.get(SEC_CTX_ATTR) == null;
     }
 
     /** {@inheritDoc} */
     @Override public SecurityContext securityContext() {
-        SecurityContext res = OperationContext.get(SEC_CTX);
+        SecurityContextWrapper secCtx = OperationContext.get(SEC_CTX_ATTR);
+
+        if (secCtx == null)
+            return dfltSecCtx;
+
+        if (secCtx.delegate() == null)
+            secCtx.delegate(securityContext(secCtx.subjId));
 
-        return res == null ? dfltSecCtx : res;
+        return secCtx.delegate();
+    }
+
+    /** */
+    private SecurityContext securityContext(UUID subjId) {
+        try {
+            SecurityContext res = secPrc.securityContext(subjId);
+
+            if (res == null) {
+                res = findNodeSecurityContext(subjId);
+
+                if (res == null)
+                    throw new IllegalStateException("Failed to find security 
context for subject with given ID : " + subjId);
+            }
+
+            return res;
+        }
+        catch (Throwable e) {
+            log.error(FAILED_OBTAIN_SEC_CTX_MSG, e);
+
+            throw e;
+        }
     }
 
     /** {@inheritDoc} */
@@ -236,6 +253,8 @@ public class IgniteSecurityProcessor extends 
IgniteSecurityAdapter {
     @Override public void start() throws IgniteCheckedException {
         super.start();
 
+        
ctx.operationContextDispatcher().registerDistributedAttribute(SECURITY.id(), 
SEC_CTX_ATTR);
+
         ctx.addNodeAttribute(ATTR_GRID_SEC_PROC_CLASS, 
secPrc.getClass().getName());
 
         secPrc.start();
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextWrapper.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextWrapper.java
new file mode 100644
index 00000000000..81777e5629f
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextWrapper.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.security;
+
+import java.util.UUID;
+import org.apache.ignite.internal.Order;
+import 
org.apache.ignite.internal.thread.context.DistributedOperationContextAttribute;
+import org.apache.ignite.internal.thread.context.OperationContextDispatcher;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.security.SecuritySubject;
+
+/**
+ * {@link SecurityContext} attribute value holder and message for {@link 
SecuritySubject}'s id.
+ *
+ * @see OperationContextDispatcher#collectDistributedAttributes()
+ * @see DistributedOperationContextAttribute#SECURITY
+ */
+public class SecurityContextWrapper implements Message {
+    /** A value of {@link SecuritySubject#id()} */
+    @Order(0)
+    UUID subjId;
+
+    /** Transient, effective {@link SecurityContext}. */
+    private SecurityContext delegate;
+
+    /** Empty constructor for serialization purposes. */
+    public SecurityContextWrapper() {
+        // No-op.
+    }
+
+    /** */
+    public SecurityContextWrapper(SecurityContext delegate) {
+        this.delegate = delegate;
+        this.subjId = delegate.subject().id();
+    }
+
+    /** */
+    public SecurityContext delegate() {
+        return delegate;
+    }
+
+    /** */
+    public void delegate(SecurityContext delegate) {
+        this.delegate = delegate;
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttribute.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttribute.java
new file mode 100644
index 00000000000..7c6899fec0e
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttribute.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.thread.context;
+
+import org.apache.ignite.internal.processors.security.SecurityContext;
+import org.apache.ignite.internal.processors.security.SecurityContextWrapper;
+
+/** Ids of Ignite's known distributed operation context attributes. */
+public enum DistributedOperationContextAttribute {
+    /**
+     * Distributed {@link SecurityContext}.
+     *
+     * @see SecurityContextWrapper
+     */
+    SECURITY;
+
+    /** Cluster-wide id of distributed attribute. */
+    public byte id() {
+        return (byte)ordinal();
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java
index a0669286576..11f56e032bf 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java
@@ -44,6 +44,7 @@ import org.jetbrains.annotations.Nullable;
  *
  * @see OperationContext
  * @see OperationContextMessage
+ * @see DistributedOperationContextAttribute
  */
 public class OperationContextDispatcher {
     /** Maximal number of supported distributed attributes. */
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties 
b/modules/core/src/main/resources/META-INF/classnames.properties
index 4e14099e871..431e7ee68b9 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -705,7 +705,6 @@ 
org.apache.ignite.internal.managers.checkpoint.GridCheckpointManager$CheckpointS
 org.apache.ignite.internal.managers.checkpoint.GridCheckpointRequest
 
org.apache.ignite.internal.managers.communication.GridIoManager$ConcurrentHashMap0
 org.apache.ignite.internal.managers.communication.GridIoMessage
-org.apache.ignite.internal.managers.communication.GridIoSecurityAwareMessage
 org.apache.ignite.internal.managers.communication.GridIoUserMessage
 org.apache.ignite.internal.managers.communication.IgniteIoTestMessage
 org.apache.ignite.internal.managers.communication.SessionChannelMessage
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessorTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessorTest.java
index 32da11cbc7d..44a272821bb 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessorTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessorTest.java
@@ -17,21 +17,20 @@
 
 package org.apache.ignite.internal.processors.security;
 
-import java.lang.reflect.Method;
 import java.util.UUID;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteDiagnosticRequest;
 import org.apache.ignite.internal.IgniteEx;
-import org.apache.ignite.internal.managers.GridManagerAdapter;
-import 
org.apache.ignite.internal.managers.communication.GridIoSecurityAwareMessage;
-import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
+import org.apache.ignite.internal.processors.security.impl.TestSecurityContext;
+import org.apache.ignite.internal.processors.security.impl.TestSecuritySubject;
+import org.apache.ignite.internal.thread.context.Scope;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.ListeningTestLogger;
 import org.apache.ignite.testframework.LogListener;
 import org.junit.Test;
 
 import static org.apache.ignite.internal.GridTopic.TOPIC_CACHE;
-import static 
org.apache.ignite.internal.managers.communication.GridIoPolicy.PUBLIC_POOL;
+import static 
org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
 
 /**
  * Unit test for {@link IgniteSecurityProcessor}.
@@ -60,15 +59,8 @@ public class IgniteSecurityProcessorTest extends 
AbstractSecurityTest {
     @Test
     public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() 
throws Exception {
         IgniteEx srv = startGridAllowAll("srv");
-
         IgniteEx cli = startClientAllowAll("cli");
 
-        Method getSpiMethod = 
GridManagerAdapter.class.getDeclaredMethod("getSpi");
-
-        getSpiMethod.setAccessible(true);
-
-        TcpCommunicationSpi spi = 
(TcpCommunicationSpi)getSpiMethod.invoke(cli.context().io());
-
         LogListener logPattern = LogListener
             .matches(s -> s.contains("Failed to obtain a security context."))
             .times(1)
@@ -76,15 +68,11 @@ public class IgniteSecurityProcessorTest extends 
AbstractSecurityTest {
 
         listeningLog.registerListener(logPattern);
 
-        spi.sendMessage(srv.localNode(), new GridIoSecurityAwareMessage(
-            UUID.randomUUID(),
-            PUBLIC_POOL,
-            TOPIC_CACHE,
-            new IgniteDiagnosticRequest(),
-            false,
-            0,
-            false
-        ));
+        TestSecurityContext unknownCtx = new TestSecurityContext(new 
TestSecuritySubject().setId(UUID.randomUUID()));
+
+        try (Scope ignored = cli.context().security().withContext(unknownCtx)) 
{
+            cli.context().io().sendToGridTopic(srv.localNode().id(), 
TOPIC_CACHE, new IgniteDiagnosticRequest(), SYSTEM_POOL);
+        }
 
         GridTestUtils.waitForCondition(logPattern::check, getTestTimeout());
     }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java
index b4003de3bcf..c14f52087d4 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java
@@ -877,14 +877,16 @@ public class OperationContextAttributesTest extends 
GridCommonAbstractTest {
             @Override public void start(PluginContext ctx) {
                 GridKernalContext kctx = ((IgniteEx)ctx.grid()).context();
 
-                
kctx.operationContextDispatcher().registerDistributedAttribute(0, dAttr1);
+                int dAttr1Id = OperationContextDispatcher.MAX_ATTRS_CNT - 2;
+                int dAttr2Id = OperationContextDispatcher.MAX_ATTRS_CNT - 1;
 
-                
kctx.operationContextDispatcher().registerDistributedAttribute(OperationContextDispatcher.MAX_ATTRS_CNT
 - 1, dAttr2);
+                
kctx.operationContextDispatcher().registerDistributedAttribute(dAttr1Id, 
dAttr1);
+                
kctx.operationContextDispatcher().registerDistributedAttribute(dAttr2Id, 
dAttr2);
 
                 assertThrowsAnyCause(
                     log,
                     () -> {
-                        
kctx.operationContextDispatcher().registerDistributedAttribute(0, 
otherTestAttr);
+                        
kctx.operationContextDispatcher().registerDistributedAttribute(dAttr2Id, 
otherTestAttr);
                         return null;
 
                     }, IgniteException.class,

Reply via email to