From f388bf96b8c1d7f1f2bfcaffc6108808a6be0113 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 29 May 2026 16:05:15 +0300 Subject: [PATCH 01/24] try --- .../thread/context/OperationContext.java | 2 +- .../context/OperationContextAttribute.java | 4 +- .../ignite/internal/CoreMessagesProvider.java | 10 +- .../OperationContexAttributeMessage.java | 43 +++++++++ .../internal/OperationContexMessage.java | 96 +++++++++++++++++++ .../OperationContextAttributeType.java | 62 ++++++++++++ .../managers/communication/GridIoManager.java | 30 +++--- .../managers/communication/GridIoMessage.java | 6 ++ .../GridIoSecurityAwareMessage.java | 68 ------------- .../security/SecuritySubjectMessage.java | 45 +++++++++ .../resources/META-INF/classnames.properties | 1 - .../security/IgniteSecurityProcessorTest.java | 19 ++-- 12 files changed, 289 insertions(+), 97 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/OperationContexAttributeMessage.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/OperationContextAttributeType.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoSecurityAwareMessage.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecuritySubjectMessage.java diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java index 6953d8b853891..4050634f90b61 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java @@ -307,7 +307,7 @@ private int mergeUpdatedAttributeBits(AttributeValueHolder[] attrVals) { } /** Immutable container that stores an attribute and its corresponding value. */ - private static class AttributeValueHolder { + public static class AttributeValueHolder { /** */ private final OperationContextAttribute attr; diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java index 499d241d9ccba..2a80df28d54d3 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java @@ -32,7 +32,7 @@ public class OperationContextAttribute { static final AtomicInteger ID_GEN = new AtomicInteger(); /** */ - static final int MAX_ATTR_CNT = Integer.SIZE; + public static final int MAX_ATTR_CNT = Integer.SIZE; /** */ private final int bitmask; @@ -41,7 +41,7 @@ public class OperationContextAttribute { @Nullable private final T initVal; /** */ - private OperationContextAttribute(int bitmask, @Nullable T initVal) { + public OperationContextAttribute(int bitmask, @Nullable T initVal) { this.bitmask = bitmask; this.initVal = initVal; } 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 fc9e3e1145970..949800eaf84f1 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.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; @@ -229,6 +228,7 @@ import org.apache.ignite.internal.processors.query.stat.messages.StatisticsResponse; import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultRequest; import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultResponse; +import org.apache.ignite.internal.processors.security.SecuritySubjectMessage; import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResultBatch; @@ -602,7 +602,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(GridIoMessage.class); withNoSchema(IgniteIoTestMessage.class); withSchema(GridIoUserMessage.class); - withSchema(GridIoSecurityAwareMessage.class); + ++msgIdx; // Former GridIoSecurityAwareMessage. withNoSchema(RecoveryLastReceivedMessage.class); withNoSchema(TcpInverseConnectionResponseMessage.class); withNoSchema(SessionChannelMessage.class); @@ -670,6 +670,12 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(PartitionHashRecord.class); withNoSchema(TransactionsHashRecord.class); + // [13400 - 13600]: Operation context messages. + msgIdx = 13400; + withNoSchema(OperationContexAttributeMessage.class); + withNoSchema(OperationContexMessage.class); + withNoSchema(SecuritySubjectMessage.class); + assert msgIdx <= MAX_MESSAGE_ID; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexAttributeMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexAttributeMessage.java new file mode 100644 index 0000000000000..bb847fa744c43 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexAttributeMessage.java @@ -0,0 +1,43 @@ +/* + * 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; + +import org.apache.ignite.internal.thread.context.OperationContextAttribute; +import org.apache.ignite.plugin.extensions.communication.Message; + +/** Transport of {@link OperationContextAttribute}. */ +public class OperationContexAttributeMessage implements Message { + /** Operation context attribute type. */ + @Order(0) + OperationContextAttributeType type; + + /** Operation context attribute value. */ + @Order(1) + Message val; + + /** Empty constructor for serialization purposes. */ + public OperationContexAttributeMessage() { + // No-op. + } + + /** Creates operation context attribute message. */ + public OperationContexAttributeMessage(OperationContextAttributeType type, Message val) { + this.type = type; + this.val = val; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java new file mode 100644 index 0000000000000..562cde21a5f4a --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java @@ -0,0 +1,96 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.List; +import org.apache.ignite.internal.thread.context.OperationContext; +import org.apache.ignite.internal.thread.context.OperationContextAttribute; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.jetbrains.annotations.Nullable; + +/** Transport of {@link OperationContext}. */ +public class OperationContexMessage implements Message { + /** Expected maximal number of operation context attributes. Is for message size optimization. */ + private static final int DFLT_EXPECTED_MAX_ATTRIBUTES_NUMBER = 5; + + /** Effective operation context attributes and their values. */ + @Order(0) + List opCtxAttrs; + + /** + * Mapping of the attributes: attribute id -> effective attribute index + 1. + * If attributes index is 0, corresponding attribute is not set. + */ + @Order(1) + byte[] attrsMapping = new byte[OperationContextAttribute.MAX_ATTR_CNT]; + + /** Empty constructor for serialization purposes. */ + public OperationContexMessage() { + // No-op. + } + + /** */ + public boolean hasAttribute(OperationContextAttributeType attrType) { + assert attrType.id() >= 0 && attrType.id() < attrsMapping.length; + + return attrsMapping[attrType.id()] > 0; + } + + /** */ + public @Nullable T attributeValue(OperationContextAttributeType attrType) { + assert attrType.id() >= 0 && attrType.id() < attrsMapping.length; + + byte idx = attrsMapping[attrType.id()]; + + if (idx < 1) + return null; + + --idx; + + assert idx < opCtxAttrs.size(); + + OperationContexAttributeMessage attrMsg = opCtxAttrs.get(idx); + + assert attrMsg != null; + assert attrMsg.type == attrType; + + return (T)attrMsg.val; + } + + /** */ + public static OperationContexMessage enrich( + @Nullable OperationContexMessage msg, + OperationContextAttributeType attrType, + Message attrVal + ) { + if (msg == null) { + msg = new OperationContexMessage(); + + msg.opCtxAttrs = new ArrayList<>(DFLT_EXPECTED_MAX_ATTRIBUTES_NUMBER); + } + + assert attrType.id() >= 0 && attrType.id() < msg.attrsMapping.length; + + msg.opCtxAttrs.add(new OperationContexAttributeMessage(attrType, attrVal)); + + msg.attrsMapping[attrType.id()] = (byte)msg.opCtxAttrs.size(); + + return msg; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContextAttributeType.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContextAttributeType.java new file mode 100644 index 0000000000000..144c7e862cafe --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/OperationContextAttributeType.java @@ -0,0 +1,62 @@ +/* + * 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; + +import org.apache.ignite.internal.processors.security.SecuritySubjectMessage; +import org.apache.ignite.internal.thread.context.OperationContextAttribute; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.jetbrains.annotations.Nullable; + +/** + * Type of {@link OperationContextAttribute}. + */ +public enum OperationContextAttributeType { + /** */ + SECURITY(SecuritySubjectMessage.class); + + /** Attribute value type. */ + private final Class valType; + + /** */ + private OperationContextAttributeType(Class valType) { + this.valType = valType; + } + + /** */ + public OperationContextAttribute create(OperationContextAttributeType type, @Nullable T initVal) { + assert type == null || initVal.getClass().isAssignableFrom(type()); + + return new OperationContextAttribute<>(type.id(), initVal); + } + + /** */ + public Class type() { + return valType; + } + + /** + * Attribute id (number). Limited by {@link OperationContextAttribute#MAX_ATTR_CNT}. + * + * @see OperationContextAttribute#bitmask() + */ + public byte id() { + assert (byte)ordinal() < OperationContextAttribute.MAX_ATTR_CNT; + + return (byte)ordinal(); + } +} 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 3acf503561ad8..ceb9f7c38886d 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 @@ -83,6 +83,8 @@ import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.NodeStoppingException; +import org.apache.ignite.internal.OperationContexMessage; +import org.apache.ignite.internal.OperationContextAttributeType; import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException; import org.apache.ignite.internal.direct.DirectMessageReader; import org.apache.ignite.internal.direct.DirectMessageWriter; @@ -97,6 +99,7 @@ import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory; import org.apache.ignite.internal.processors.platform.message.PlatformMessageFilter; import org.apache.ignite.internal.processors.pool.PoolProcessor; +import org.apache.ignite.internal.processors.security.SecuritySubjectMessage; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; import org.apache.ignite.internal.processors.tracing.MTC; import org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings; @@ -137,7 +140,6 @@ 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; @@ -2025,11 +2027,8 @@ private long getInverseConnectionWaitTimeout() { 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}. */ + private GridIoMessage createGridIoMessage( Object topic, Message msg, byte plc, @@ -2037,16 +2036,18 @@ private long getInverseConnectionWaitTimeout() { long timeout, boolean skipOnTimeout ) { + GridIoMessage res = new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); + if (ctx.security().enabled()) { - UUID secSubjId = null; + assert res.opCtxMsg == null : "Several context operation attributes aren't supported yet."; - if (!ctx.security().isDefaultContext()) - secSubjId = ctx.security().securityContext().subject().id(); + UUID secSubjId = ctx.security().isDefaultContext() ? null : ctx.security().securityContext().subject().id(); - return new GridIoSecurityAwareMessage(secSubjId, plc, topic, msg, ordered, timeout, skipOnTimeout); + res.opCtxMsg = OperationContexMessage.enrich(res.opCtxMsg, OperationContextAttributeType.SECURITY, + new SecuritySubjectMessage(secSubjId)); } - return new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); + return res; } /** @@ -4236,9 +4237,12 @@ public long binLatencyMcs() { */ private UUID secSubjId(GridIoMessage msg) { if (ctx.security().enabled()) { - assert msg instanceof GridIoSecurityAwareMessage; + assert msg.opCtxMsg != null; + assert msg.opCtxMsg.hasAttribute(OperationContextAttributeType.SECURITY); + + SecuritySubjectMessage secSubjMsg = msg.opCtxMsg.attributeValue(OperationContextAttributeType.SECURITY); - return ((GridIoSecurityAwareMessage)msg).securitySubjectId(); + return secSubjMsg.id; } return null; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java index 8cc6c106cf22e..f6a099481ac2b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java @@ -19,6 +19,7 @@ import org.apache.ignite.internal.ExecutorAwareMessage; import org.apache.ignite.internal.GridTopicMessage; +import org.apache.ignite.internal.OperationContexMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.datastreamer.DataStreamerRequest; @@ -64,6 +65,11 @@ public class GridIoMessage implements Message, SpanTransport { @Order(6) byte[] span; + /** Effective operation context attributes. */ + @Order(7) + @GridToStringInclude + public @Nullable OperationContexMessage opCtxMsg; + /** * Default constructor. */ 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 d1a6040d3d682..0000000000000 --- 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/processors/security/SecuritySubjectMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecuritySubjectMessage.java new file mode 100644 index 0000000000000..a14029562d188 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecuritySubjectMessage.java @@ -0,0 +1,45 @@ +/* + * 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.io.Serializable; +import java.util.UUID; +import org.apache.ignite.internal.OperationContextAttributeType; +import org.apache.ignite.internal.Order; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.jetbrains.annotations.Nullable; + +/** A message for {@link OperationContextAttributeType#SECURITY}. */ +public class SecuritySubjectMessage implements Message, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Security subject identifier. */ + @Order(0) + public @Nullable UUID id; + + /** Empty constructor for serialization purposes */ + public SecuritySubjectMessage() { + // No-op. + } + + /** */ + public SecuritySubjectMessage(@Nullable UUID id) { + this.id = id; + } +} diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties index e009043efb02d..4b550be9e993b 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 32da11cbc7da6..1936660a570e0 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 @@ -22,8 +22,10 @@ import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteDiagnosticRequest; import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.OperationContexMessage; +import org.apache.ignite.internal.OperationContextAttributeType; import org.apache.ignite.internal.managers.GridManagerAdapter; -import org.apache.ignite.internal.managers.communication.GridIoSecurityAwareMessage; +import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.ListeningTestLogger; @@ -76,15 +78,12 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex listeningLog.registerListener(logPattern); - spi.sendMessage(srv.localNode(), new GridIoSecurityAwareMessage( - UUID.randomUUID(), - PUBLIC_POOL, - TOPIC_CACHE, - new IgniteDiagnosticRequest(), - false, - 0, - false - )); + GridIoMessage msg = new GridIoMessage(PUBLIC_POOL, TOPIC_CACHE, new IgniteDiagnosticRequest(), false, 0, false); + + msg.opCtxMsg = OperationContexMessage.enrich(null, OperationContextAttributeType.SECURITY, + new SecuritySubjectMessage(UUID.randomUUID())); + + spi.sendMessage(srv.localNode(), msg); GridTestUtils.waitForCondition(logPattern::check, getTestTimeout()); } From 86dfef827a698f913ef1b7b0fe33849f6ff6c736 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 26 Jun 2026 13:11:55 +0300 Subject: [PATCH 02/24] raw --- .../thread/context/OperationContext.java | 2 +- .../context/OperationContextAttribute.java | 4 +- .../ignite/internal/CoreMessagesProvider.java | 14 +-- .../OperationContexAttributeMessage.java | 43 --------- .../internal/OperationContexMessage.java | 96 ------------------- .../OperationContextAttributeType.java | 62 ------------ .../managers/communication/GridIoManager.java | 48 ++++------ .../discovery/GridDiscoveryManager.java | 26 ++--- .../SecurityAwareCustomMessageWrapper.java | 75 --------------- .../IgniteAuthenticationProcessor.java | 2 +- .../security/IgniteSecurityProcessor.java | 16 +++- ...ssage.java => SecurityContextMessage.java} | 27 +++--- .../ignite/internal/util/IgniteUtils.java | 12 +-- .../security/IgniteSecurityProcessorTest.java | 2 - .../NodeSecurityContextPropagationTest.java | 3 - .../OperationContextAttributesTest.java | 8 +- 16 files changed, 78 insertions(+), 362 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/OperationContexAttributeMessage.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/OperationContextAttributeType.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java rename modules/core/src/main/java/org/apache/ignite/internal/processors/security/{SecuritySubjectMessage.java => SecurityContextMessage.java} (64%) diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java index ab4ca064970d8..4a8f556781cf7 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java @@ -307,7 +307,7 @@ private int mergeUpdatedAttributeBits(AttributeValueHolder[] attrVals) { } /** Immutable container that stores an attribute and its corresponding value. */ - public static class AttributeValueHolder { + private static class AttributeValueHolder { /** */ private final OperationContextAttribute attr; diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java index 2a80df28d54d3..499d241d9ccba 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java @@ -32,7 +32,7 @@ public class OperationContextAttribute { static final AtomicInteger ID_GEN = new AtomicInteger(); /** */ - public static final int MAX_ATTR_CNT = Integer.SIZE; + static final int MAX_ATTR_CNT = Integer.SIZE; /** */ private final int bitmask; @@ -41,7 +41,7 @@ public class OperationContextAttribute { @Nullable private final T initVal; /** */ - public OperationContextAttribute(int bitmask, @Nullable T initVal) { + private OperationContextAttribute(int bitmask, @Nullable T initVal) { this.bitmask = bitmask; this.initVal = initVal; } 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 96dfbe5887960..4158d33258299 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 @@ -34,7 +34,6 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean; import org.apache.ignite.internal.managers.deployment.GridDeploymentRequest; import org.apache.ignite.internal.managers.deployment.GridDeploymentResponse; -import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.managers.encryption.ChangeCacheEncryptionRequest; import org.apache.ignite.internal.managers.encryption.EncryptionDataBagItem; import org.apache.ignite.internal.managers.encryption.GenerateEncryptionKeyRequest; @@ -238,6 +237,7 @@ 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.SecurityContextMessage; import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResultBatch; @@ -436,7 +436,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(FullMessage.class); withNoSchema(InitMessage.class); withNoSchema(CacheStatisticsModeChangeMessage.class); - withNoSchema(SecurityAwareCustomMessageWrapper.class); + ++msgIdx; // Former SecurityAwareCustomMessageWrapper withNoSchema(MetadataRemoveAcceptedMessage.class); withNoSchema(MetadataRemoveProposedMessage.class); withNoSchema(WalStateFinishMessage.class); @@ -605,12 +605,14 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [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); - ++msgIdx; // Former GridIoSecurityAwareMessage. + withSchema(GridIoSecurityAwareMessage.class); withNoSchema(RecoveryLastReceivedMessage.class); withNoSchema(TcpInverseConnectionResponseMessage.class); withNoSchema(SessionChannelMessage.class); @@ -687,10 +689,10 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13500]: Operation context messages. msgIdx = 13400; withNoSchema(OperationContextMessage.class); - withNoSchema(SecuritySubjectMessage.class); + withNoSchema(SecurityContextMessage.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/OperationContexAttributeMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexAttributeMessage.java deleted file mode 100644 index bb847fa744c43..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexAttributeMessage.java +++ /dev/null @@ -1,43 +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; - -import org.apache.ignite.internal.thread.context.OperationContextAttribute; -import org.apache.ignite.plugin.extensions.communication.Message; - -/** Transport of {@link OperationContextAttribute}. */ -public class OperationContexAttributeMessage implements Message { - /** Operation context attribute type. */ - @Order(0) - OperationContextAttributeType type; - - /** Operation context attribute value. */ - @Order(1) - Message val; - - /** Empty constructor for serialization purposes. */ - public OperationContexAttributeMessage() { - // No-op. - } - - /** Creates operation context attribute message. */ - public OperationContexAttributeMessage(OperationContextAttributeType type, Message val) { - this.type = type; - this.val = val; - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java deleted file mode 100644 index 562cde21a5f4a..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java +++ /dev/null @@ -1,96 +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; - -import java.util.ArrayList; -import java.util.List; -import org.apache.ignite.internal.thread.context.OperationContext; -import org.apache.ignite.internal.thread.context.OperationContextAttribute; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.jetbrains.annotations.Nullable; - -/** Transport of {@link OperationContext}. */ -public class OperationContexMessage implements Message { - /** Expected maximal number of operation context attributes. Is for message size optimization. */ - private static final int DFLT_EXPECTED_MAX_ATTRIBUTES_NUMBER = 5; - - /** Effective operation context attributes and their values. */ - @Order(0) - List opCtxAttrs; - - /** - * Mapping of the attributes: attribute id -> effective attribute index + 1. - * If attributes index is 0, corresponding attribute is not set. - */ - @Order(1) - byte[] attrsMapping = new byte[OperationContextAttribute.MAX_ATTR_CNT]; - - /** Empty constructor for serialization purposes. */ - public OperationContexMessage() { - // No-op. - } - - /** */ - public boolean hasAttribute(OperationContextAttributeType attrType) { - assert attrType.id() >= 0 && attrType.id() < attrsMapping.length; - - return attrsMapping[attrType.id()] > 0; - } - - /** */ - public @Nullable T attributeValue(OperationContextAttributeType attrType) { - assert attrType.id() >= 0 && attrType.id() < attrsMapping.length; - - byte idx = attrsMapping[attrType.id()]; - - if (idx < 1) - return null; - - --idx; - - assert idx < opCtxAttrs.size(); - - OperationContexAttributeMessage attrMsg = opCtxAttrs.get(idx); - - assert attrMsg != null; - assert attrMsg.type == attrType; - - return (T)attrMsg.val; - } - - /** */ - public static OperationContexMessage enrich( - @Nullable OperationContexMessage msg, - OperationContextAttributeType attrType, - Message attrVal - ) { - if (msg == null) { - msg = new OperationContexMessage(); - - msg.opCtxAttrs = new ArrayList<>(DFLT_EXPECTED_MAX_ATTRIBUTES_NUMBER); - } - - assert attrType.id() >= 0 && attrType.id() < msg.attrsMapping.length; - - msg.opCtxAttrs.add(new OperationContexAttributeMessage(attrType, attrVal)); - - msg.attrsMapping[attrType.id()] = (byte)msg.opCtxAttrs.size(); - - return msg; - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContextAttributeType.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContextAttributeType.java deleted file mode 100644 index 144c7e862cafe..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/OperationContextAttributeType.java +++ /dev/null @@ -1,62 +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; - -import org.apache.ignite.internal.processors.security.SecuritySubjectMessage; -import org.apache.ignite.internal.thread.context.OperationContextAttribute; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.jetbrains.annotations.Nullable; - -/** - * Type of {@link OperationContextAttribute}. - */ -public enum OperationContextAttributeType { - /** */ - SECURITY(SecuritySubjectMessage.class); - - /** Attribute value type. */ - private final Class valType; - - /** */ - private OperationContextAttributeType(Class valType) { - this.valType = valType; - } - - /** */ - public OperationContextAttribute create(OperationContextAttributeType type, @Nullable T initVal) { - assert type == null || initVal.getClass().isAssignableFrom(type()); - - return new OperationContextAttribute<>(type.id(), initVal); - } - - /** */ - public Class type() { - return valType; - } - - /** - * Attribute id (number). Limited by {@link OperationContextAttribute#MAX_ATTR_CNT}. - * - * @see OperationContextAttribute#bitmask() - */ - public byte id() { - assert (byte)ordinal() < OperationContextAttribute.MAX_ATTR_CNT; - - return (byte)ordinal(); - } -} 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 c01c0f80f3f48..8d1e3745993dc 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 @@ -83,8 +83,6 @@ import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.NodeStoppingException; -import org.apache.ignite.internal.OperationContexMessage; -import org.apache.ignite.internal.OperationContextAttributeType; import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException; import org.apache.ignite.internal.direct.DirectMessageReader; import org.apache.ignite.internal.direct.DirectMessageWriter; @@ -99,12 +97,14 @@ import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory; import org.apache.ignite.internal.processors.platform.message.PlatformMessageFilter; import org.apache.ignite.internal.processors.pool.PoolProcessor; -import org.apache.ignite.internal.processors.security.SecuritySubjectMessage; +import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; +import org.apache.ignite.internal.processors.security.SecurityContextMessage; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; import org.apache.ignite.internal.processors.tracing.MTC; import org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings; import org.apache.ignite.internal.processors.tracing.Span; import org.apache.ignite.internal.processors.tracing.SpanTags; +import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashSet; import org.apache.ignite.internal.util.IgniteUtils; @@ -1319,7 +1319,7 @@ private void processP2PMessage( assert obj != null; - invokeListener(msg.policy(), lsnr, nodeId, obj, secSubjId(msg)); + invokeListener(msg.policy(), lsnr, nodeId, obj); } finally { threadProcessingMessage(false, null); @@ -1457,7 +1457,7 @@ private void processRegularMessage0(GridIoMessage msg, UUID nodeId) { assert obj != null; - invokeListener(msg.policy(), lsnr, nodeId, obj, secSubjId(msg)); + invokeListener(msg.policy(), lsnr, nodeId, obj); } /** @@ -1821,9 +1821,8 @@ private void unwindMessageSet(GridCommunicationMessageSet msgSet, GridMessageLis * @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(); @@ -1833,7 +1832,9 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj if (change) CUR_PLC.set(plc); - UUID newSecSubjId = secSubjId != null ? secSubjId : nodeId; + SecurityContextMessage secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); + + UUID newSecSubjId = secCtxMsg == null ? nodeId : secCtxMsg.subjId; try (Scope ignored = ctx.security().withContext(newSecSubjId)) { lsnr.onMessage(nodeId, msg, plc); @@ -2042,18 +2043,16 @@ private GridIoMessage createGridIoMessage( ) { GridIoMessage res; - if (ctx.security().enabled()) { - UUID secSubjId = null; + UUID secSubjId = ctx.security().enabled() && !ctx.security().isDefaultContext() + ? ctx.security().securityContext().subject().id() + : null; - if (!ctx.security().isDefaultContext()) - secSubjId = ctx.security().securityContext().subject().id(); + res = new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); - res = new GridIoSecurityAwareMessage(secSubjId, plc, topic, msg, ordered, timeout, skipOnTimeout); + try (Scope ignored = secSubjId == null ? Scope.NOOP_SCOPE + : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextMessage(secSubjId))) { + res.opCtxMsg = ctx.operationContextDispatcher().collectDistributedAttributes(); } - else - res = new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); - - res.opCtxMsg = ctx.operationContextDispatcher().collectDistributedAttributes(); return res; } @@ -3811,7 +3810,7 @@ void unwind(GridMessageListener lsnr) { 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) @@ -4240,19 +4239,6 @@ public long binLatencyMcs() { } } - /** - * @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/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java index d7a599271f04e..6ddfdb14ea0c0 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 @@ -88,14 +88,16 @@ import org.apache.ignite.internal.processors.cluster.ChangeGlobalStateMessage; import org.apache.ignite.internal.processors.cluster.DiscoveryDataClusterState; import org.apache.ignite.internal.processors.cluster.IGridClusterStateProcessor; -import org.apache.ignite.internal.processors.security.IgniteSecurity; +import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; +import org.apache.ignite.internal.processors.security.SecurityContextMessage; import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.systemview.ClusterNodeViewWalker; import org.apache.ignite.internal.systemview.NodeAttributeViewWalker; import org.apache.ignite.internal.systemview.NodeMetricsViewWalker; import org.apache.ignite.internal.thread.OomExceptionHandler; import org.apache.ignite.internal.thread.context.OperationContext; +import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.context.function.OperationContextAwareWrapper; import org.apache.ignite.internal.util.GridAtomicLong; @@ -134,7 +136,6 @@ import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider; import org.apache.ignite.spi.discovery.DiscoveryNotification; import org.apache.ignite.spi.discovery.DiscoverySpi; -import org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage; import org.apache.ignite.spi.discovery.DiscoverySpiDataExchange; import org.apache.ignite.spi.discovery.DiscoverySpiHistorySupport; import org.apache.ignite.spi.discovery.DiscoverySpiListener; @@ -226,7 +227,7 @@ public class GridDiscoveryManager extends GridManagerAdapter { }; /** Discovery cached history size. */ - private final int DISCOVERY_HISTORY_SIZE = getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, DFLT_DISCOVERY_HISTORY_SIZE); + private static final int DISCOVERY_HISTORY_SIZE = getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, DFLT_DISCOVERY_HISTORY_SIZE); /** */ private final Object discoEvtMux = new Object(); @@ -929,12 +930,10 @@ public SecurityAwareNotificationTask(DiscoveryNotification notification) { /** */ @Override public void run() { - DiscoverySpiCustomMessage customMsg = notification.customMessage(); + SecurityContextMessage secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); - if (customMsg instanceof SecurityAwareCustomMessageWrapper) { - UUID secSubjId = ((SecurityAwareCustomMessageWrapper)customMsg).securitySubjectId(); - - try (Scope ignored = ctx.security().withContext(secSubjId)) { + if (secCtxMsg != null) { + try (Scope ignored = ctx.security().withContext(secCtxMsg.subjId)) { super.run(); } } @@ -2339,12 +2338,13 @@ public GridFutureAdapter localJoinFuture() { * @throws IgniteCheckedException If failed. */ public void sendCustomEvent(DiscoveryCustomMessage msg) throws IgniteCheckedException { - try { - IgniteSecurity security = ctx.security(); + UUID secSubjId = ctx.security().enabled() ? ctx.security().securityContext().subject().id() : null; - getSpi().sendCustomEvent(security.enabled() - ? new SecurityAwareCustomMessageWrapper(msg, security.securityContext().subject().id()) - : msg); + try (Scope ignored = secSubjId == null + ? Scope.NOOP_SCOPE + : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextMessage(secSubjId)) + ) { + getSpi().sendCustomEvent(msg); } catch (IgniteClientDisconnectedException e) { IgniteFuture reconnectFut = ctx.cluster().clientReconnectFuture(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java deleted file mode 100644 index e9d33b8433cbf..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java +++ /dev/null @@ -1,75 +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.discovery; - -import java.util.UUID; -import org.apache.ignite.internal.Order; -import org.apache.ignite.plugin.extensions.communication.MessageFactory; -import org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage; -import org.jetbrains.annotations.Nullable; - -/** Custom message wrapper with ID of security subject that initiated the current message. */ -public class SecurityAwareCustomMessageWrapper implements DiscoverySpiCustomMessage { - /** Security subject ID. */ - @Order(0) - UUID secSubjId; - - /** Original message. */ - @Order(1) - DiscoveryCustomMessage delegate; - - /** Default constructor for {@link MessageFactory}. */ - public SecurityAwareCustomMessageWrapper() { - // No-op. - } - - /** */ - public SecurityAwareCustomMessageWrapper(DiscoveryCustomMessage delegate, UUID secSubjId) { - this.delegate = delegate; - this.secSubjId = secSubjId; - } - - /** Gets security Subject ID. */ - public UUID securitySubjectId() { - return secSubjId; - } - - /** {@inheritDoc} */ - @Override public boolean isMutable() { - return delegate().isMutable(); - } - - /** {@inheritDoc} */ - @Override public boolean stopProcess() { - return delegate().stopProcess(); - } - - /** - * @return Delegate. - */ - public DiscoveryCustomMessage delegate() { - return delegate; - } - - /** {@inheritDoc} */ - @Override public @Nullable DiscoverySpiCustomMessage ackMessage() { - DiscoveryCustomMessage ack = (DiscoveryCustomMessage)delegate().ackMessage(); - - return ack == null ? null : new SecurityAwareCustomMessageWrapper(ack, secSubjId); - } -} 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 55a5c22f2a813..74a7dca34a827 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 @@ private RefreshUsersStorageWorker(ArrayList usrs) { } /** {@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 7b34ed75db2dc..1495f227eaec9 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 @@ -24,6 +24,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.cluster.ClusterNode; @@ -88,8 +89,11 @@ static boolean hasSandboxedNodes() { return SANDBOXED_NODES_COUNTER.get() > 0; } - /** Context attribute that holds Security Context. */ - private static final OperationContextAttribute SEC_CTX = OperationContextAttribute.newInstance(); + /** Security Context holder. */ + private static final AtomicReference SEC_CTX = new AtomicReference<>(); + + /** Distributed attribute holding Security Context data to resend. */ + public static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); /** Security processor. */ private final GridSecurityProcessor secPrc; @@ -126,7 +130,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public Scope withContext(SecurityContext secCtx) { - return OperationContext.set(SEC_CTX, secCtx == dfltSecCtx ? null : secCtx); + return SEC_CTX, secCtx == dfltSecCtx ? null : secCtx); } /** {@inheritDoc} */ @@ -172,12 +176,12 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@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); + SecurityContext res = OperationContext.get(SEC_CTX_ATTR); return res == null ? dfltSecCtx : res; } @@ -236,6 +240,8 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP @Override public void start() throws IgniteCheckedException { super.start(); + ctx.operationContextDispatcher().registerDistributedAttribute(0, 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/SecuritySubjectMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java similarity index 64% rename from modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecuritySubjectMessage.java rename to modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java index a14029562d188..79333397eb3e6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecuritySubjectMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java @@ -17,29 +17,30 @@ package org.apache.ignite.internal.processors.security; -import java.io.Serializable; import java.util.UUID; -import org.apache.ignite.internal.OperationContextAttributeType; import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.plugin.extensions.communication.Message; -import org.jetbrains.annotations.Nullable; +import org.apache.ignite.plugin.security.SecuritySubject; -/** A message for {@link OperationContextAttributeType#SECURITY}. */ -public class SecuritySubjectMessage implements Message, Serializable { +/** + * Message for {@link SecurityContext}. + * + * @see SecuritySubject + * @see OperationContextDispatcher + */ +public class SecurityContextMessage implements Message { /** */ - private static final long serialVersionUID = 0L; - - /** Security subject identifier. */ @Order(0) - public @Nullable UUID id; + public UUID subjId; - /** Empty constructor for serialization purposes */ - public SecuritySubjectMessage() { + /** Empty constructor for serialization purposes. */ + public SecurityContextMessage() { // No-op. } /** */ - public SecuritySubjectMessage(@Nullable UUID id) { - this.id = id; + public SecurityContextMessage(UUID subjId) { + this.subjId = subjId; } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 1513346138589..6e57e19b0fb1d 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -188,7 +188,6 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo; import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage; import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; -import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.mxbean.IgniteStandardMXBean; import org.apache.ignite.internal.processors.cache.CacheDefaultBinaryAffinityKeyMapper; import org.apache.ignite.internal.processors.cache.CacheObjectContext; @@ -8116,7 +8115,7 @@ public void clearAllListener() { /** */ public static IgniteDataTransferObjectSerializer loadSerializer(Class cls) { try { - Class cls0 = IgniteUtils.class.getClassLoader() + Class cls0 = IgniteUtils.class.getClassLoader() .loadClass(cls.getPackage().getName() + "." + cls.getSimpleName() + "Serializer"); return (IgniteDataTransferObjectSerializer)cls0.getDeclaredConstructor().newInstance(); @@ -8128,12 +8127,13 @@ public static IgniteDataTransferObjectSeria } /** - * Unwraps messsage if it is wrapped by {@link SecurityAwareCustomMessageWrapper}. + * Unwraps messsage as {@link DiscoveryCustomMessage}. * * @param msg Message. */ - public static DiscoveryCustomMessage unwrapCustomMessage(DiscoverySpiCustomMessage msg) { - return msg instanceof SecurityAwareCustomMessageWrapper ? - ((SecurityAwareCustomMessageWrapper)msg).delegate() : (DiscoveryCustomMessage)msg; + public static DiscoveryCustomMessage unwrapCustomMessage(@Nullable DiscoverySpiCustomMessage msg) { + assert msg == null || msg instanceof DiscoveryCustomMessage; + + return (DiscoveryCustomMessage)msg; } } 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 1936660a570e0..971b3ed5f67dc 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 @@ -22,8 +22,6 @@ import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteDiagnosticRequest; import org.apache.ignite.internal.IgniteEx; -import org.apache.ignite.internal.OperationContexMessage; -import org.apache.ignite.internal.OperationContextAttributeType; import org.apache.ignite.internal.managers.GridManagerAdapter; import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java index 6e33bed666079..701a003b3881d 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java @@ -34,7 +34,6 @@ import org.apache.ignite.failure.StopNodeOrHaltFailureHandler; import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.events.DiscoveryCustomEvent; -import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.spi.MessagesPluginProvider; import org.apache.ignite.spi.discovery.DiscoverySpi; @@ -186,8 +185,6 @@ private boolean anyReceivedMessageMatch(IgniteEx ignite, Predicate predi if (msg instanceof TcpDiscoveryCustomEventMessage) { DiscoverySpiCustomMessage customMsg = ((TcpDiscoveryCustomEventMessage)msg).message(); - assert customMsg instanceof SecurityAwareCustomMessageWrapper; - unwrappedMsg = U.unwrapCustomMessage(customMsg); } 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 b4003de3bcf72..c14f52087d400 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 @@ private void doTestOperationContextAttributesPropagation(boolean discovery) thro @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, From 5defc7a536b2438129652e24dbae578d3ecd6b10 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 26 Jun 2026 13:50:16 +0300 Subject: [PATCH 03/24] raw --- .../ignite/internal/CoreMessagesProvider.java | 6 +- .../managers/communication/GridIoManager.java | 6 +- .../discovery/GridDiscoveryManager.java | 7 +- .../IgniteAuthenticationProcessor.java | 74 +---------- .../security/IgniteSecurityProcessor.java | 10 +- .../security/SecurityContextImpl.java | 123 ++++++++++++++++++ .../security/SecurityContextMessage.java | 46 ------- .../security/IgniteSecurityProcessorTest.java | 9 +- 8 files changed, 141 insertions(+), 140 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java 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 4158d33258299..cf79c8c48db80 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 @@ -237,7 +237,7 @@ 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.SecurityContextMessage; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResultBatch; @@ -612,7 +612,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(GridIoMessage.class); withNoSchema(IgniteIoTestMessage.class); withSchema(GridIoUserMessage.class); - withSchema(GridIoSecurityAwareMessage.class); + ++msgIdx; // Former GridIoSecurityAwareMessage withNoSchema(RecoveryLastReceivedMessage.class); withNoSchema(TcpInverseConnectionResponseMessage.class); withNoSchema(SessionChannelMessage.class); @@ -689,7 +689,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13500]: Operation context messages. msgIdx = 13400; withNoSchema(OperationContextMessage.class); - withNoSchema(SecurityContextMessage.class); + withNoSchema(SecurityContextImpl.class); // [13600 - 13700]: Rolling Upgrade messages. msgIdx = 13600; 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 8d1e3745993dc..658ca82e25c5b 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 @@ -98,7 +98,7 @@ import org.apache.ignite.internal.processors.platform.message.PlatformMessageFilter; import org.apache.ignite.internal.processors.pool.PoolProcessor; import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; -import org.apache.ignite.internal.processors.security.SecurityContextMessage; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; import org.apache.ignite.internal.processors.tracing.MTC; import org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings; @@ -1832,7 +1832,7 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj if (change) CUR_PLC.set(plc); - SecurityContextMessage secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); + SecurityContextImpl secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); UUID newSecSubjId = secCtxMsg == null ? nodeId : secCtxMsg.subjId; @@ -2050,7 +2050,7 @@ private GridIoMessage createGridIoMessage( res = new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); try (Scope ignored = secSubjId == null ? Scope.NOOP_SCOPE - : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextMessage(secSubjId))) { + : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextImpl(secSubjId))) { res.opCtxMsg = ctx.operationContextDispatcher().collectDistributedAttributes(); } 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 6ddfdb14ea0c0..b13b8ee104f39 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 @@ -90,14 +90,13 @@ import org.apache.ignite.internal.processors.cluster.IGridClusterStateProcessor; import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; -import org.apache.ignite.internal.processors.security.SecurityContextMessage; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.systemview.ClusterNodeViewWalker; import org.apache.ignite.internal.systemview.NodeAttributeViewWalker; import org.apache.ignite.internal.systemview.NodeMetricsViewWalker; import org.apache.ignite.internal.thread.OomExceptionHandler; import org.apache.ignite.internal.thread.context.OperationContext; -import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.context.function.OperationContextAwareWrapper; import org.apache.ignite.internal.util.GridAtomicLong; @@ -930,7 +929,7 @@ public SecurityAwareNotificationTask(DiscoveryNotification notification) { /** */ @Override public void run() { - SecurityContextMessage secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); + SecurityContextImpl secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); if (secCtxMsg != null) { try (Scope ignored = ctx.security().withContext(secCtxMsg.subjId)) { @@ -2342,7 +2341,7 @@ public void sendCustomEvent(DiscoveryCustomMessage msg) throws IgniteCheckedExce try (Scope ignored = secSubjId == null ? Scope.NOOP_SCOPE - : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextMessage(secSubjId)) + : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextImpl(secSubjId)) ) { getSpi().sendCustomEvent(msg); } 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 74a7dca34a827..3aab17857a63d 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 @@ -17,7 +17,6 @@ package org.apache.ignite.internal.processors.authentication; -import java.io.Serializable; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; @@ -57,12 +56,12 @@ import org.apache.ignite.internal.processors.security.GridSecurityProcessor; import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.CU; -import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.lang.IgniteFuture; @@ -73,7 +72,6 @@ import org.apache.ignite.plugin.security.SecurityException; import org.apache.ignite.plugin.security.SecurityPermission; import org.apache.ignite.plugin.security.SecuritySubject; -import org.apache.ignite.plugin.security.SecuritySubjectType; import org.apache.ignite.spi.discovery.DiscoveryDataBag; import org.apache.ignite.spi.discovery.DiscoverySpi; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; @@ -1331,74 +1329,4 @@ private RefreshUsersStorageWorker(ArrayList usrs) { } } } - - /** Represents {@link SecuritySubject} implementation. */ - private static class SecuritySubjectImpl implements SecuritySubject { - /** */ - private static final long serialVersionUID = 0L; - - /** Security subject identifier. */ - private final UUID id; - - /** Security subject login. */ - private final String login; - - /** Security subject type. */ - private final SecuritySubjectType type; - - /** Security subject address. */ - private final InetSocketAddress addr; - - /** */ - public SecuritySubjectImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - this.id = id; - this.login = login; - this.type = type; - this.addr = addr; - } - - /** {@inheritDoc} */ - @Override public UUID id() { - return id; - } - - /** {@inheritDoc} */ - @Override public String login() { - return login; - } - - /** {@inheritDoc} */ - @Override public SecuritySubjectType type() { - return type; - } - - /** {@inheritDoc} */ - @Override public InetSocketAddress address() { - return addr; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(SecuritySubjectImpl.class, this); - } - } - - /** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ - private static class SecurityContextImpl implements SecurityContext, Serializable { - /** */ - private static final long serialVersionUID = 0L; - - /** */ - private final SecuritySubject subj; - - /** */ - public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - subj = new SecuritySubjectImpl(id, login, type, addr); - } - - /** {@inheritDoc} */ - @Override public SecuritySubject subject() { - return subj; - } - } } 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 1495f227eaec9..6c7cf57f95e9e 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 @@ -24,7 +24,6 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.cluster.ClusterNode; @@ -89,11 +88,8 @@ static boolean hasSandboxedNodes() { return SANDBOXED_NODES_COUNTER.get() > 0; } - /** Security Context holder. */ - private static final AtomicReference SEC_CTX = new AtomicReference<>(); - - /** Distributed attribute holding Security Context data to resend. */ - public static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); + /** Attribute that holds local and distributed Security Context. */ + public static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); /** Security processor. */ private final GridSecurityProcessor secPrc; @@ -130,7 +126,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public Scope withContext(SecurityContext secCtx) { - return SEC_CTX, secCtx == dfltSecCtx ? null : secCtx); + return OperationContext.set(SEC_CTX_ATTR, secCtx == dfltSecCtx ? null : SecurityContextImpl.of(secCtx)); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java new file mode 100644 index 0000000000000..02deae0d2358c --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java @@ -0,0 +1,123 @@ +/* + * 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.io.Serializable; +import java.net.InetSocketAddress; +import java.util.UUID; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.security.SecuritySubject; +import org.apache.ignite.plugin.security.SecuritySubjectType; +import org.jetbrains.annotations.Nullable; + +/** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ +public class SecurityContextImpl implements SecurityContext, Message, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Security subject identifier. */ + @Order(0) + public UUID subjId; + + /** */ + private @Nullable SecuritySubject subj; + + /** Empty constructor for serialization purposes. */ + public SecurityContextImpl() { + // No-op. + } + + /** Constructor to be a {@link Message} only. */ + public SecurityContextImpl(UUID subjId) { + this.subjId = subjId; + } + + /** */ + public SecurityContextImpl(SecuritySubject subj) { + this.subjId = subj.id(); + this.subj = subj; + } + + /** */ + public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { + subjId = id; + subj = new SecuritySubjectImpl(login, type, addr); + } + + /** */ + public static @Nullable SecurityContextImpl of(@Nullable SecurityContext ctx) { + if (ctx == null || ctx instanceof SecurityContextImpl) + return (SecurityContextImpl)ctx; + + return new SecurityContextImpl(ctx.subject()); + } + + /** {@inheritDoc} */ + @Override public @Nullable SecuritySubject subject() { + return subj; + } + + /** Represents {@link SecuritySubject} implementation. */ + private class SecuritySubjectImpl implements SecuritySubject { + /** */ + private static final long serialVersionUID = 0L; + + /** Security subject login. */ + private final String login; + + /** Security subject type. */ + private final SecuritySubjectType type; + + /** Security subject address. */ + private final InetSocketAddress addr; + + /** */ + private SecuritySubjectImpl(String login, SecuritySubjectType type, InetSocketAddress addr) { + this.login = login; + this.type = type; + this.addr = addr; + } + + /** {@inheritDoc} */ + @Override public UUID id() { + return subjId; + } + + /** {@inheritDoc} */ + @Override public String login() { + return login; + } + + /** {@inheritDoc} */ + @Override public SecuritySubjectType type() { + return type; + } + + /** {@inheritDoc} */ + @Override public InetSocketAddress address() { + return addr; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(SecuritySubjectImpl.class, this); + } + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java deleted file mode 100644 index 79333397eb3e6..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java +++ /dev/null @@ -1,46 +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.processors.security; - -import java.util.UUID; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.thread.context.OperationContextDispatcher; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.apache.ignite.plugin.security.SecuritySubject; - -/** - * Message for {@link SecurityContext}. - * - * @see SecuritySubject - * @see OperationContextDispatcher - */ -public class SecurityContextMessage implements Message { - /** */ - @Order(0) - public UUID subjId; - - /** Empty constructor for serialization purposes. */ - public SecurityContextMessage() { - // No-op. - } - - /** */ - public SecurityContextMessage(UUID subjId) { - this.subjId = subjId; - } -} 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 971b3ed5f67dc..4e69d61c91f2e 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 @@ -24,6 +24,8 @@ import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.managers.GridManagerAdapter; import org.apache.ignite.internal.managers.communication.GridIoMessage; +import org.apache.ignite.internal.thread.context.OperationContext; +import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.ListeningTestLogger; @@ -78,10 +80,9 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex GridIoMessage msg = new GridIoMessage(PUBLIC_POOL, TOPIC_CACHE, new IgniteDiagnosticRequest(), false, 0, false); - msg.opCtxMsg = OperationContexMessage.enrich(null, OperationContextAttributeType.SECURITY, - new SecuritySubjectMessage(UUID.randomUUID())); - - spi.sendMessage(srv.localNode(), msg); + try (Scope ignored = OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextImpl(UUID.randomUUID()))) { + spi.sendMessage(srv.localNode(), msg); + } GridTestUtils.waitForCondition(logPattern::check, getTestTimeout()); } From 6d3bf1c9a399db5c93d4db4d192aaa68bdf01786 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 29 Jun 2026 15:38:35 +0300 Subject: [PATCH 04/24] split from Disco changes --- .../ignite/internal/CoreMessagesProvider.java | 3 +- .../discovery/GridDiscoveryManager.java | 23 +++--- .../SecurityAwareCustomMessageWrapper.java | 75 +++++++++++++++++++ .../ignite/internal/util/IgniteUtils.java | 12 +-- .../NodeSecurityContextPropagationTest.java | 3 + 5 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java 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 cf79c8c48db80..4ade893630fc0 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 @@ -34,6 +34,7 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean; import org.apache.ignite.internal.managers.deployment.GridDeploymentRequest; import org.apache.ignite.internal.managers.deployment.GridDeploymentResponse; +import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.managers.encryption.ChangeCacheEncryptionRequest; import org.apache.ignite.internal.managers.encryption.EncryptionDataBagItem; import org.apache.ignite.internal.managers.encryption.GenerateEncryptionKeyRequest; @@ -436,7 +437,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(FullMessage.class); withNoSchema(InitMessage.class); withNoSchema(CacheStatisticsModeChangeMessage.class); - ++msgIdx; // Former SecurityAwareCustomMessageWrapper + withNoSchema(SecurityAwareCustomMessageWrapper.class); withNoSchema(MetadataRemoveAcceptedMessage.class); withNoSchema(MetadataRemoveProposedMessage.class); withNoSchema(WalStateFinishMessage.class); 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 b13b8ee104f39..23877a26244fc 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 @@ -88,9 +88,8 @@ import org.apache.ignite.internal.processors.cluster.ChangeGlobalStateMessage; import org.apache.ignite.internal.processors.cluster.DiscoveryDataClusterState; import org.apache.ignite.internal.processors.cluster.IGridClusterStateProcessor; -import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; +import org.apache.ignite.internal.processors.security.IgniteSecurity; import org.apache.ignite.internal.processors.security.SecurityContext; -import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.systemview.ClusterNodeViewWalker; import org.apache.ignite.internal.systemview.NodeAttributeViewWalker; @@ -135,6 +134,7 @@ import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider; import org.apache.ignite.spi.discovery.DiscoveryNotification; import org.apache.ignite.spi.discovery.DiscoverySpi; +import org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage; import org.apache.ignite.spi.discovery.DiscoverySpiDataExchange; import org.apache.ignite.spi.discovery.DiscoverySpiHistorySupport; import org.apache.ignite.spi.discovery.DiscoverySpiListener; @@ -929,10 +929,12 @@ public SecurityAwareNotificationTask(DiscoveryNotification notification) { /** */ @Override public void run() { - SecurityContextImpl secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); + DiscoverySpiCustomMessage customMsg = notification.customMessage(); - if (secCtxMsg != null) { - try (Scope ignored = ctx.security().withContext(secCtxMsg.subjId)) { + if (customMsg instanceof SecurityAwareCustomMessageWrapper) { + UUID secSubjId = ((SecurityAwareCustomMessageWrapper)customMsg).securitySubjectId(); + + try (Scope ignored = ctx.security().withContext(secSubjId)) { super.run(); } } @@ -2337,13 +2339,12 @@ public GridFutureAdapter localJoinFuture() { * @throws IgniteCheckedException If failed. */ public void sendCustomEvent(DiscoveryCustomMessage msg) throws IgniteCheckedException { - UUID secSubjId = ctx.security().enabled() ? ctx.security().securityContext().subject().id() : null; + try { + IgniteSecurity security = ctx.security(); - try (Scope ignored = secSubjId == null - ? Scope.NOOP_SCOPE - : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextImpl(secSubjId)) - ) { - getSpi().sendCustomEvent(msg); + getSpi().sendCustomEvent(security.enabled() + ? new SecurityAwareCustomMessageWrapper(msg, security.securityContext().subject().id()) + : msg); } catch (IgniteClientDisconnectedException e) { IgniteFuture reconnectFut = ctx.cluster().clientReconnectFuture(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java new file mode 100644 index 0000000000000..e9d33b8433cbf --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java @@ -0,0 +1,75 @@ +/* + * 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.discovery; + +import java.util.UUID; +import org.apache.ignite.internal.Order; +import org.apache.ignite.plugin.extensions.communication.MessageFactory; +import org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage; +import org.jetbrains.annotations.Nullable; + +/** Custom message wrapper with ID of security subject that initiated the current message. */ +public class SecurityAwareCustomMessageWrapper implements DiscoverySpiCustomMessage { + /** Security subject ID. */ + @Order(0) + UUID secSubjId; + + /** Original message. */ + @Order(1) + DiscoveryCustomMessage delegate; + + /** Default constructor for {@link MessageFactory}. */ + public SecurityAwareCustomMessageWrapper() { + // No-op. + } + + /** */ + public SecurityAwareCustomMessageWrapper(DiscoveryCustomMessage delegate, UUID secSubjId) { + this.delegate = delegate; + this.secSubjId = secSubjId; + } + + /** Gets security Subject ID. */ + public UUID securitySubjectId() { + return secSubjId; + } + + /** {@inheritDoc} */ + @Override public boolean isMutable() { + return delegate().isMutable(); + } + + /** {@inheritDoc} */ + @Override public boolean stopProcess() { + return delegate().stopProcess(); + } + + /** + * @return Delegate. + */ + public DiscoveryCustomMessage delegate() { + return delegate; + } + + /** {@inheritDoc} */ + @Override public @Nullable DiscoverySpiCustomMessage ackMessage() { + DiscoveryCustomMessage ack = (DiscoveryCustomMessage)delegate().ackMessage(); + + return ack == null ? null : new SecurityAwareCustomMessageWrapper(ack, secSubjId); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 6e57e19b0fb1d..1513346138589 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -188,6 +188,7 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo; import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage; import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; +import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.mxbean.IgniteStandardMXBean; import org.apache.ignite.internal.processors.cache.CacheDefaultBinaryAffinityKeyMapper; import org.apache.ignite.internal.processors.cache.CacheObjectContext; @@ -8115,7 +8116,7 @@ public void clearAllListener() { /** */ public static IgniteDataTransferObjectSerializer loadSerializer(Class cls) { try { - Class cls0 = IgniteUtils.class.getClassLoader() + Class cls0 = IgniteUtils.class.getClassLoader() .loadClass(cls.getPackage().getName() + "." + cls.getSimpleName() + "Serializer"); return (IgniteDataTransferObjectSerializer)cls0.getDeclaredConstructor().newInstance(); @@ -8127,13 +8128,12 @@ public static IgniteDataTransferObjectSeria } /** - * Unwraps messsage as {@link DiscoveryCustomMessage}. + * Unwraps messsage if it is wrapped by {@link SecurityAwareCustomMessageWrapper}. * * @param msg Message. */ - public static DiscoveryCustomMessage unwrapCustomMessage(@Nullable DiscoverySpiCustomMessage msg) { - assert msg == null || msg instanceof DiscoveryCustomMessage; - - return (DiscoveryCustomMessage)msg; + public static DiscoveryCustomMessage unwrapCustomMessage(DiscoverySpiCustomMessage msg) { + return msg instanceof SecurityAwareCustomMessageWrapper ? + ((SecurityAwareCustomMessageWrapper)msg).delegate() : (DiscoveryCustomMessage)msg; } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java index 701a003b3881d..6e33bed666079 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java @@ -34,6 +34,7 @@ import org.apache.ignite.failure.StopNodeOrHaltFailureHandler; import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.events.DiscoveryCustomEvent; +import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.spi.MessagesPluginProvider; import org.apache.ignite.spi.discovery.DiscoverySpi; @@ -185,6 +186,8 @@ private boolean anyReceivedMessageMatch(IgniteEx ignite, Predicate predi if (msg instanceof TcpDiscoveryCustomEventMessage) { DiscoverySpiCustomMessage customMsg = ((TcpDiscoveryCustomEventMessage)msg).message(); + assert customMsg instanceof SecurityAwareCustomMessageWrapper; + unwrappedMsg = U.unwrapCustomMessage(customMsg); } From 9529036c25dbee4ceb2f6fd7f3336a23246392ba Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 30 Jun 2026 12:28:12 +0300 Subject: [PATCH 05/24] Minor javadoc, test fix --- .../internal/managers/communication/GridIoManager.java | 2 +- .../processors/security/SecurityContextImpl.java | 9 +++++++-- .../processors/security/IgniteSecurityProcessorTest.java | 7 +++++-- 3 files changed, 13 insertions(+), 5 deletions(-) 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 658ca82e25c5b..295af677e170b 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 @@ -2033,7 +2033,7 @@ private long getInverseConnectionWaitTimeout() { } /** @return A {@link GridIoMessage} wrapper for {@code msg}. */ - private GridIoMessage createGridIoMessage( + public GridIoMessage createGridIoMessage( Object topic, Message msg, byte plc, diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java index 02deae0d2358c..cfe08cedfded0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java @@ -27,7 +27,12 @@ import org.apache.ignite.plugin.security.SecuritySubjectType; import org.jetbrains.annotations.Nullable; -/** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ +/** + * Represents {@link SecurityContext} implementation that ignores any security permission checks and is able to transfer + * id of {@link SecuritySubject} as a {@link Message}. + * + * @see #SecurityContextImpl(UUID) + */ public class SecurityContextImpl implements SecurityContext, Message, Serializable { /** */ private static final long serialVersionUID = 0L; @@ -44,7 +49,7 @@ public SecurityContextImpl() { // No-op. } - /** Constructor to be a {@link Message} only. */ + /** Constructor to be a {@link Message} only. Doesn't suppose working with {@link #subject()}. */ public SecurityContextImpl(UUID subjId) { this.subjId = subjId; } 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 4e69d61c91f2e..b4deedd38aad3 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 @@ -24,6 +24,7 @@ import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.managers.GridManagerAdapter; import org.apache.ignite.internal.managers.communication.GridIoMessage; +import org.apache.ignite.internal.processors.security.impl.TestSecuritySubject; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; @@ -78,9 +79,11 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex listeningLog.registerListener(logPattern); - GridIoMessage msg = new GridIoMessage(PUBLIC_POOL, TOPIC_CACHE, new IgniteDiagnosticRequest(), false, 0, false); + SecurityContextImpl testSecCtx = new SecurityContextImpl(new TestSecuritySubject().setId(UUID.randomUUID())); + + try (Scope ignored = OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, testSecCtx)) { + GridIoMessage msg = cli.context().io().createGridIoMessage(TOPIC_CACHE, new IgniteDiagnosticRequest(), PUBLIC_POOL, false, 0, false); - try (Scope ignored = OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextImpl(UUID.randomUUID()))) { spi.sendMessage(srv.localNode(), msg); } From cf98fb8c136aca101ea6d96ab37f7afccf7d5304 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 30 Jun 2026 12:37:21 +0300 Subject: [PATCH 06/24] even better test --- .../internal/managers/communication/GridIoManager.java | 2 +- .../processors/security/IgniteSecurityProcessorTest.java | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) 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 295af677e170b..658ca82e25c5b 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 @@ -2033,7 +2033,7 @@ private long getInverseConnectionWaitTimeout() { } /** @return A {@link GridIoMessage} wrapper for {@code msg}. */ - public GridIoMessage createGridIoMessage( + private GridIoMessage createGridIoMessage( Object topic, Message msg, byte plc, 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 b4deedd38aad3..e66bafef0e241 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 @@ -23,11 +23,9 @@ 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.GridIoMessage; import org.apache.ignite.internal.processors.security.impl.TestSecuritySubject; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.internal.thread.context.Scope; -import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.ListeningTestLogger; import org.apache.ignite.testframework.LogListener; @@ -70,8 +68,6 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex 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) @@ -82,9 +78,7 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex SecurityContextImpl testSecCtx = new SecurityContextImpl(new TestSecuritySubject().setId(UUID.randomUUID())); try (Scope ignored = OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, testSecCtx)) { - GridIoMessage msg = cli.context().io().createGridIoMessage(TOPIC_CACHE, new IgniteDiagnosticRequest(), PUBLIC_POOL, false, 0, false); - - spi.sendMessage(srv.localNode(), msg); + cli.context().io().sendToGridTopic(srv.localNode(), TOPIC_CACHE, new IgniteDiagnosticRequest(), PUBLIC_POOL); } GridTestUtils.waitForCondition(logPattern::check, getTestTimeout()); From e689503275cc6fbca310256d09eed47b5a37cbb6 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 30 Jun 2026 23:25:13 +0300 Subject: [PATCH 07/24] test fix --- .../IgniteExchangeLatchManagerDiscoHistoryTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java index d7bde459fa589..a48531289bcaa 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java @@ -52,6 +52,7 @@ import org.junit.Test; import static org.apache.ignite.IgniteSystemProperties.IGNITE_DISCOVERY_HISTORY_SIZE; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; /** * Test {@link ExchangeLatchManager} throws {@link IgniteException} with appropriate message when topology history @@ -204,7 +205,7 @@ public void testProperException() throws Exception { final long topVer = 2; // Starting server nodes to exhaust the topology history. - for (int i = 2; i < 3 * TOPOLOGY_HISTORY_SIZE && !disco.isEmptyTopologyHistory(topVer); ++i) { + for (int i = 2; i < 2 + TOPOLOGY_HISTORY_SIZE; ++i) { final int currNodeIdx = i; final int joinedNodesCnt = disco.totalJoinedNodes(); @@ -212,18 +213,16 @@ public void testProperException() throws Exception { srvFuts.add(GridTestUtils.runAsync(() -> startGrid(currNodeIdx))); assertTrue("Failed to wait for a new server node [joinedNodesCnt=" + joinedNodesCnt + "]", - GridTestUtils.waitForCondition( + waitForCondition( () -> disco.totalJoinedNodes() >= (joinedNodesCnt + 1), DEFAULT_TIMEOUT)); } - assertTrue( - "Disco cache history is not empty for the topology [majorTopVer=" + topVer + ']', - disco.isEmptyTopologyHistory(topVer)); + assertTrue(waitForCondition(() -> disco.isEmptyTopologyHistory(topVer), getTestTimeout(), 50)); // Let's continue the ongoing exchange. exchangeLatch.countDown(); - boolean failureHnd = GridTestUtils.waitForCondition(() -> cpFailureCtx.get() != null, DEFAULT_TIMEOUT); + boolean failureHnd = waitForCondition(() -> cpFailureCtx.get() != null, DEFAULT_TIMEOUT); assertNull( "Unexpected exception (probably, the topology history still exists [err=" + err + ']', From 02f16096f9b81c84170cb9840e06189d53e55b86 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 1 Jul 2026 09:00:28 +0300 Subject: [PATCH 08/24] fix --- .../discovery/GridDiscoveryManager.java | 6 +++--- .../security/SecurityContextImpl.java | 19 +++++++++++++------ ...eExchangeLatchManagerDiscoHistoryTest.java | 11 ++++++----- 3 files changed, 22 insertions(+), 14 deletions(-) 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 23877a26244fc..91a27237ade7f 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 { }; /** Discovery cached history size. */ - private static final int DISCOVERY_HISTORY_SIZE = getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, DFLT_DISCOVERY_HISTORY_SIZE); + private final int discHistSz = getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, DFLT_DISCOVERY_HISTORY_SIZE); /** */ private final Object discoEvtMux = new Object(); @@ -254,7 +254,7 @@ public class GridDiscoveryManager extends GridManagerAdapter { /** Topology cache history. */ private final GridBoundedConcurrentLinkedHashMap discoCacheHist = - new GridBoundedConcurrentLinkedHashMap<>(DISCOVERY_HISTORY_SIZE); + new GridBoundedConcurrentLinkedHashMap<>(discHistSz); /** Topology snapshots history. */ private volatile NavigableMap> topHist = Collections.emptyNavigableMap(); @@ -1107,7 +1107,7 @@ private boolean skipMessage(int type, @Nullable DiscoveryCustomMessage customMsg rcvdCustomMsgs.addLast(customMsg.id()); - while (rcvdCustomMsgs.size() > DISCOVERY_HISTORY_SIZE) + while (rcvdCustomMsgs.size() > discHistSz) rcvdCustomMsgs.pollFirst(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java index cfe08cedfded0..12034ed60fc1b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java @@ -21,6 +21,7 @@ import java.net.InetSocketAddress; import java.util.UUID; import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.security.SecuritySubject; @@ -28,10 +29,13 @@ import org.jetbrains.annotations.Nullable; /** - * Represents {@link SecurityContext} implementation that ignores any security permission checks and is able to transfer - * id of {@link SecuritySubject} as a {@link Message}. + *

Represents {@link SecurityContext} implementation that ignores any security permission checks.

Transfers {@link SecuritySubject#id()} operation context attribute as a {@link Message}.

* - * @see #SecurityContextImpl(UUID) + * @see SecurityContextImpl(UUID) + * @see SecuritySubjectImpl#id() + * @see IgniteSecurityProcessor#SEC_CTX_ATTR + * @see OperationContextDispatcher */ public class SecurityContextImpl implements SecurityContext, Message, Serializable { /** */ @@ -66,7 +70,7 @@ public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, Inet subj = new SecuritySubjectImpl(login, type, addr); } - /** */ + /** Casts to or wraps with {@link SecurityContextImpl} passed {@ctx}. */ public static @Nullable SecurityContextImpl of(@Nullable SecurityContext ctx) { if (ctx == null || ctx instanceof SecurityContextImpl) return (SecurityContextImpl)ctx; @@ -79,7 +83,10 @@ public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, Inet return subj; } - /** Represents {@link SecuritySubject} implementation. */ + /** + * Implementation of {@link SecuritySubject} linked to parent {@link SecurityContextImpl}. + * Follows {@link SecurityContextImpl#subjId}. + */ private class SecuritySubjectImpl implements SecuritySubject { /** */ private static final long serialVersionUID = 0L; @@ -100,7 +107,7 @@ private SecuritySubjectImpl(String login, SecuritySubjectType type, InetSocketAd this.addr = addr; } - /** {@inheritDoc} */ + /** @return {@link SecurityContextImpl#subjId}. */ @Override public UUID id() { return subjId; } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java index a48531289bcaa..d7bde459fa589 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java @@ -52,7 +52,6 @@ import org.junit.Test; import static org.apache.ignite.IgniteSystemProperties.IGNITE_DISCOVERY_HISTORY_SIZE; -import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; /** * Test {@link ExchangeLatchManager} throws {@link IgniteException} with appropriate message when topology history @@ -205,7 +204,7 @@ public void testProperException() throws Exception { final long topVer = 2; // Starting server nodes to exhaust the topology history. - for (int i = 2; i < 2 + TOPOLOGY_HISTORY_SIZE; ++i) { + for (int i = 2; i < 3 * TOPOLOGY_HISTORY_SIZE && !disco.isEmptyTopologyHistory(topVer); ++i) { final int currNodeIdx = i; final int joinedNodesCnt = disco.totalJoinedNodes(); @@ -213,16 +212,18 @@ public void testProperException() throws Exception { srvFuts.add(GridTestUtils.runAsync(() -> startGrid(currNodeIdx))); assertTrue("Failed to wait for a new server node [joinedNodesCnt=" + joinedNodesCnt + "]", - waitForCondition( + GridTestUtils.waitForCondition( () -> disco.totalJoinedNodes() >= (joinedNodesCnt + 1), DEFAULT_TIMEOUT)); } - assertTrue(waitForCondition(() -> disco.isEmptyTopologyHistory(topVer), getTestTimeout(), 50)); + assertTrue( + "Disco cache history is not empty for the topology [majorTopVer=" + topVer + ']', + disco.isEmptyTopologyHistory(topVer)); // Let's continue the ongoing exchange. exchangeLatch.countDown(); - boolean failureHnd = waitForCondition(() -> cpFailureCtx.get() != null, DEFAULT_TIMEOUT); + boolean failureHnd = GridTestUtils.waitForCondition(() -> cpFailureCtx.get() != null, DEFAULT_TIMEOUT); assertNull( "Unexpected exception (probably, the topology history still exists [err=" + err + ']', From 54231db61c152e5e987079def080f36864e61432 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 12:11:52 +0300 Subject: [PATCH 09/24] review fix --- .../ignite/internal/CoreMessagesProvider.java | 4 +- .../managers/communication/GridIoManager.java | 25 ++-- .../IgniteAuthenticationProcessor.java | 74 +++++++++- .../security/IgniteSecurityProcessor.java | 23 ++- .../security/SecurityContextImpl.java | 135 ------------------ .../security/SecurityContextMessage.java | 48 +++++++ .../security/IgniteSecurityProcessorTest.java | 23 ++- 7 files changed, 169 insertions(+), 163 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java 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 14fef8e6ef99b..1fc9f8f127102 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 @@ -239,7 +239,7 @@ 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.SecurityContextImpl; +import org.apache.ignite.internal.processors.security.SecurityContextMessage; import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResultBatch; @@ -692,7 +692,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13500]: Operation context messages. msgIdx = 13400; withNoSchema(OperationContextMessage.class); - withNoSchema(SecurityContextImpl.class); + withNoSchema(SecurityContextMessage.class); // [13600 - 13700]: Rolling Upgrade messages. msgIdx = 13600; 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 658ca82e25c5b..024e80611e2a1 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 @@ -97,14 +97,12 @@ import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory; import org.apache.ignite.internal.processors.platform.message.PlatformMessageFilter; import org.apache.ignite.internal.processors.pool.PoolProcessor; -import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; -import org.apache.ignite.internal.processors.security.SecurityContextImpl; +import org.apache.ignite.internal.processors.security.SecurityContext; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; import org.apache.ignite.internal.processors.tracing.MTC; import org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings; import org.apache.ignite.internal.processors.tracing.Span; import org.apache.ignite.internal.processors.tracing.SpanTags; -import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashSet; import org.apache.ignite.internal.util.IgniteUtils; @@ -1832,9 +1830,15 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj if (change) CUR_PLC.set(plc); - SecurityContextImpl secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); + UUID newSecSubjId; - UUID newSecSubjId = secCtxMsg == null ? nodeId : secCtxMsg.subjId; + if (ctx.security().isDefaultContext()) + newSecSubjId = ctx.security().securityContext().subject().id(); + else { + SecurityContext secCtx = ctx.security().securityContext(); + + newSecSubjId = secCtx == null ? nodeId : secCtx.subject().id(); + } try (Scope ignored = ctx.security().withContext(newSecSubjId)) { lsnr.onMessage(nodeId, msg, plc); @@ -2033,7 +2037,7 @@ private long getInverseConnectionWaitTimeout() { } /** @return A {@link GridIoMessage} wrapper for {@code msg}. */ - private GridIoMessage createGridIoMessage( + public GridIoMessage createGridIoMessage( Object topic, Message msg, byte plc, @@ -2043,16 +2047,9 @@ private GridIoMessage createGridIoMessage( ) { GridIoMessage res; - UUID secSubjId = ctx.security().enabled() && !ctx.security().isDefaultContext() - ? ctx.security().securityContext().subject().id() - : null; - res = new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); - try (Scope ignored = secSubjId == null ? Scope.NOOP_SCOPE - : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextImpl(secSubjId))) { - res.opCtxMsg = ctx.operationContextDispatcher().collectDistributedAttributes(); - } + res.opCtxMsg = ctx.operationContextDispatcher().collectDistributedAttributes(); return res; } 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 3aab17857a63d..74a7dca34a827 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 @@ -17,6 +17,7 @@ package org.apache.ignite.internal.processors.authentication; +import java.io.Serializable; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; @@ -56,12 +57,12 @@ import org.apache.ignite.internal.processors.security.GridSecurityProcessor; import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; -import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.CU; +import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.lang.IgniteFuture; @@ -72,6 +73,7 @@ import org.apache.ignite.plugin.security.SecurityException; import org.apache.ignite.plugin.security.SecurityPermission; import org.apache.ignite.plugin.security.SecuritySubject; +import org.apache.ignite.plugin.security.SecuritySubjectType; import org.apache.ignite.spi.discovery.DiscoveryDataBag; import org.apache.ignite.spi.discovery.DiscoverySpi; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; @@ -1329,4 +1331,74 @@ private RefreshUsersStorageWorker(ArrayList usrs) { } } } + + /** Represents {@link SecuritySubject} implementation. */ + private static class SecuritySubjectImpl implements SecuritySubject { + /** */ + private static final long serialVersionUID = 0L; + + /** Security subject identifier. */ + private final UUID id; + + /** Security subject login. */ + private final String login; + + /** Security subject type. */ + private final SecuritySubjectType type; + + /** Security subject address. */ + private final InetSocketAddress addr; + + /** */ + public SecuritySubjectImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { + this.id = id; + this.login = login; + this.type = type; + this.addr = addr; + } + + /** {@inheritDoc} */ + @Override public UUID id() { + return id; + } + + /** {@inheritDoc} */ + @Override public String login() { + return login; + } + + /** {@inheritDoc} */ + @Override public SecuritySubjectType type() { + return type; + } + + /** {@inheritDoc} */ + @Override public InetSocketAddress address() { + return addr; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(SecuritySubjectImpl.class, this); + } + } + + /** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ + private static class SecurityContextImpl implements SecurityContext, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + private final SecuritySubject subj; + + /** */ + public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { + subj = new SecuritySubjectImpl(id, login, type, addr); + } + + /** {@inheritDoc} */ + @Override public SecuritySubject subject() { + return subj; + } + } } 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 6c7cf57f95e9e..2a5eedeb1f596 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 @@ -72,6 +72,9 @@ * */ public class IgniteSecurityProcessor extends IgniteSecurityAdapter { + /** */ + static final byte SECURITY_CONTEXT_ATTRIBUTE_ID = 0; + /** */ private static final String FAILED_OBTAIN_SEC_CTX_MSG = "Failed to obtain a security context."; @@ -89,7 +92,7 @@ static boolean hasSandboxedNodes() { } /** Attribute that holds local and distributed Security Context. */ - public static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); + private static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); /** Security processor. */ private final GridSecurityProcessor secPrc; @@ -126,7 +129,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public Scope withContext(SecurityContext secCtx) { - return OperationContext.set(SEC_CTX_ATTR, secCtx == dfltSecCtx ? null : SecurityContextImpl.of(secCtx)); + return OperationContext.set(SEC_CTX_ATTR, secCtx == dfltSecCtx ? null : new SecurityContextMessage(secCtx)); } /** {@inheritDoc} */ @@ -177,9 +180,19 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public SecurityContext securityContext() { - SecurityContext res = OperationContext.get(SEC_CTX_ATTR); + SecurityContextMessage secCtxMsg = OperationContext.get(SEC_CTX_ATTR); + + if (secCtxMsg != null) { + if (secCtxMsg.delegate() == null) { + try (Scope ignored = withContext(secCtxMsg.subjId)) { + return securityContext(); + } + } + + return secCtxMsg.delegate(); + } - return res == null ? dfltSecCtx : res; + return dfltSecCtx; } /** {@inheritDoc} */ @@ -236,7 +249,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP @Override public void start() throws IgniteCheckedException { super.start(); - ctx.operationContextDispatcher().registerDistributedAttribute(0, SEC_CTX_ATTR); + ctx.operationContextDispatcher().registerDistributedAttribute(SECURITY_CONTEXT_ATTRIBUTE_ID, SEC_CTX_ATTR); ctx.addNodeAttribute(ATTR_GRID_SEC_PROC_CLASS, secPrc.getClass().getName()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java deleted file mode 100644 index 12034ed60fc1b..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java +++ /dev/null @@ -1,135 +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.processors.security; - -import java.io.Serializable; -import java.net.InetSocketAddress; -import java.util.UUID; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.thread.context.OperationContextDispatcher; -import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.apache.ignite.plugin.security.SecuritySubject; -import org.apache.ignite.plugin.security.SecuritySubjectType; -import org.jetbrains.annotations.Nullable; - -/** - *

Represents {@link SecurityContext} implementation that ignores any security permission checks.

Transfers {@link SecuritySubject#id()} operation context attribute as a {@link Message}.

- * - * @see SecurityContextImpl(UUID) - * @see SecuritySubjectImpl#id() - * @see IgniteSecurityProcessor#SEC_CTX_ATTR - * @see OperationContextDispatcher - */ -public class SecurityContextImpl implements SecurityContext, Message, Serializable { - /** */ - private static final long serialVersionUID = 0L; - - /** Security subject identifier. */ - @Order(0) - public UUID subjId; - - /** */ - private @Nullable SecuritySubject subj; - - /** Empty constructor for serialization purposes. */ - public SecurityContextImpl() { - // No-op. - } - - /** Constructor to be a {@link Message} only. Doesn't suppose working with {@link #subject()}. */ - public SecurityContextImpl(UUID subjId) { - this.subjId = subjId; - } - - /** */ - public SecurityContextImpl(SecuritySubject subj) { - this.subjId = subj.id(); - this.subj = subj; - } - - /** */ - public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - subjId = id; - subj = new SecuritySubjectImpl(login, type, addr); - } - - /** Casts to or wraps with {@link SecurityContextImpl} passed {@ctx}. */ - public static @Nullable SecurityContextImpl of(@Nullable SecurityContext ctx) { - if (ctx == null || ctx instanceof SecurityContextImpl) - return (SecurityContextImpl)ctx; - - return new SecurityContextImpl(ctx.subject()); - } - - /** {@inheritDoc} */ - @Override public @Nullable SecuritySubject subject() { - return subj; - } - - /** - * Implementation of {@link SecuritySubject} linked to parent {@link SecurityContextImpl}. - * Follows {@link SecurityContextImpl#subjId}. - */ - private class SecuritySubjectImpl implements SecuritySubject { - /** */ - private static final long serialVersionUID = 0L; - - /** Security subject login. */ - private final String login; - - /** Security subject type. */ - private final SecuritySubjectType type; - - /** Security subject address. */ - private final InetSocketAddress addr; - - /** */ - private SecuritySubjectImpl(String login, SecuritySubjectType type, InetSocketAddress addr) { - this.login = login; - this.type = type; - this.addr = addr; - } - - /** @return {@link SecurityContextImpl#subjId}. */ - @Override public UUID id() { - return subjId; - } - - /** {@inheritDoc} */ - @Override public String login() { - return login; - } - - /** {@inheritDoc} */ - @Override public SecuritySubjectType type() { - return type; - } - - /** {@inheritDoc} */ - @Override public InetSocketAddress address() { - return addr; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(SecuritySubjectImpl.class, this); - } - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java new file mode 100644 index 0000000000000..4a3f0218612c4 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java @@ -0,0 +1,48 @@ +/* + * 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.plugin.extensions.communication.Message; + +/** */ +public class SecurityContextMessage implements Message { + /** Security subject id. */ + @Order(0) + UUID subjId; + + /** */ + private SecurityContext delegate; + + /** Empty constructor for serialization purposes. */ + public SecurityContextMessage() { + // No-op. + } + + /** */ + public SecurityContextMessage(SecurityContext delegate) { + this.delegate = delegate; + this.subjId = delegate.subject().id(); + } + + /** */ + public SecurityContext delegate() { + return delegate; + } +} 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 e66bafef0e241..6be6eeb4abaf7 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 @@ -22,10 +22,13 @@ import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteDiagnosticRequest; import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.OperationContextMessage; import org.apache.ignite.internal.managers.GridManagerAdapter; +import org.apache.ignite.internal.managers.communication.GridIoMessage; +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.OperationContext; -import org.apache.ignite.internal.thread.context.Scope; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.ListeningTestLogger; import org.apache.ignite.testframework.LogListener; @@ -68,6 +71,8 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex 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) @@ -75,11 +80,17 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex listeningLog.registerListener(logPattern); - SecurityContextImpl testSecCtx = new SecurityContextImpl(new TestSecuritySubject().setId(UUID.randomUUID())); + GridIoMessage msg = cli.context().io().createGridIoMessage(TOPIC_CACHE, new IgniteDiagnosticRequest(), PUBLIC_POOL, + false, 0, false); + + msg.opCtxMsg = new OperationContextMessage(); + + msg.opCtxMsg.vals = new Message[]{new SecurityContextMessage(new TestSecurityContext(new TestSecuritySubject() + .setId(UUID.randomUUID())))}; + + msg.opCtxMsg.idBitmap = 1 << IgniteSecurityProcessor.SECURITY_CONTEXT_ATTRIBUTE_ID; - try (Scope ignored = OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, testSecCtx)) { - cli.context().io().sendToGridTopic(srv.localNode(), TOPIC_CACHE, new IgniteDiagnosticRequest(), PUBLIC_POOL); - } + spi.sendMessage(srv.localNode(), msg); GridTestUtils.waitForCondition(logPattern::check, getTestTimeout()); } From eb3ee17bce51e81c8a0f9448d08ab7abdbded722 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 12:21:58 +0300 Subject: [PATCH 10/24] minority --- .../internal/managers/discovery/GridDiscoveryManager.java | 6 +++--- .../processors/security/IgniteSecurityProcessor.java | 7 ++++++- .../processors/security/SecurityContextMessage.java | 8 +++++++- 3 files changed, 16 insertions(+), 5 deletions(-) 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 91a27237ade7f..7411e501b3c51 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 { }; /** Discovery cached history size. */ - private final int discHistSz = 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 { /** Topology cache history. */ private final GridBoundedConcurrentLinkedHashMap discoCacheHist = - new GridBoundedConcurrentLinkedHashMap<>(discHistSz); + new GridBoundedConcurrentLinkedHashMap<>(discoHistSz); /** Topology snapshots history. */ private volatile NavigableMap> topHist = Collections.emptyNavigableMap(); @@ -1107,7 +1107,7 @@ private boolean skipMessage(int type, @Nullable DiscoveryCustomMessage customMsg rcvdCustomMsgs.addLast(customMsg.id()); - while (rcvdCustomMsgs.size() > discHistSz) + while (rcvdCustomMsgs.size() > discoHistSz) rcvdCustomMsgs.pollFirst(); } 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 2a5eedeb1f596..e380bcb7c7ac3 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.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; @@ -91,7 +92,11 @@ static boolean hasSandboxedNodes() { return SANDBOXED_NODES_COUNTER.get() > 0; } - /** Attribute that holds local and distributed Security Context. */ + /** + * Attribute that holds local and distributed Security Context. + * + * @see OperationContextDispatcher + */ private static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); /** Security processor. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java index 4a3f0218612c4..75ec6e9b85a5c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java @@ -19,9 +19,15 @@ import java.util.UUID; import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.security.SecuritySubject; -/** */ +/** + * Transfer for {@link SecurityContext}, id of {@link SecuritySubject}. + * + * @see OperationContextDispatcher#collectDistributedAttributes() + */ public class SecurityContextMessage implements Message { /** Security subject id. */ @Order(0) From 9dbc300863bde3fa64d9a041ed99e3f5954e4c39 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 12:22:35 +0300 Subject: [PATCH 11/24] minority --- .../internal/processors/security/SecurityContextMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java index 75ec6e9b85a5c..f96609f3876a8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java @@ -29,7 +29,7 @@ * @see OperationContextDispatcher#collectDistributedAttributes() */ public class SecurityContextMessage implements Message { - /** Security subject id. */ + /** A value of {@link SecuritySubject#id()} */ @Order(0) UUID subjId; From 5ca3b6b748f83a9ff7befda3a4e301fac681cddd Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 12:23:14 +0300 Subject: [PATCH 12/24] minority --- .../internal/processors/security/SecurityContextMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java index f96609f3876a8..13eb1c9023ddd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java @@ -33,7 +33,7 @@ public class SecurityContextMessage implements Message { @Order(0) UUID subjId; - /** */ + /** Transient, effective {@link SecurityContext}. */ private SecurityContext delegate; /** Empty constructor for serialization purposes. */ From e49492074a2c6537dcdee828a8da3db27d92f969 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 14:58:35 +0300 Subject: [PATCH 13/24] review fixes --- .../managers/communication/GridIoManager.java | 24 ++++++------ .../security/IgniteSecurityProcessor.java | 38 +++++++++++++------ .../security/SecurityContextMessage.java | 5 +++ ...DistributedOperationContextAttributes.java | 31 +++++++++++++++ .../security/IgniteSecurityProcessorTest.java | 30 +++------------ 5 files changed, 81 insertions(+), 47 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java 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 024e80611e2a1..11d1649c85cf7 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 @@ -97,7 +97,6 @@ import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory; import org.apache.ignite.internal.processors.platform.message.PlatformMessageFilter; import org.apache.ignite.internal.processors.pool.PoolProcessor; -import org.apache.ignite.internal.processors.security.SecurityContext; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; import org.apache.ignite.internal.processors.tracing.MTC; import org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings; @@ -1830,17 +1829,7 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj if (change) CUR_PLC.set(plc); - UUID newSecSubjId; - - if (ctx.security().isDefaultContext()) - newSecSubjId = ctx.security().securityContext().subject().id(); - else { - SecurityContext secCtx = ctx.security().securityContext(); - - newSecSubjId = secCtx == null ? nodeId : secCtx.subject().id(); - } - - try (Scope ignored = ctx.security().withContext(newSecSubjId)) { + try (Scope ignored = attachNodeSecurityContextIfRequired(nodeId)) { lsnr.onMessage(nodeId, msg, plc); } finally { @@ -1849,6 +1838,17 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj } } + /** */ + private Scope attachNodeSecurityContextIfRequired(UUID nodeId) { + if (ctx.security().isDefaultContext()) + return ctx.security().withContext(nodeId); + + // Check that security context is valid. + ctx.security().securityContext(); + + return Scope.NOOP_SCOPE; + } + /** * @return Current IO policy */ 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 e380bcb7c7ac3..eb70adad1525f 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 @@ -32,6 +32,7 @@ import org.apache.ignite.internal.processors.security.sandbox.AccessControllerSandbox; 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.DistributedOperationContextAttributes; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.thread.context.OperationContextDispatcher; @@ -73,9 +74,6 @@ * */ public class IgniteSecurityProcessor extends IgniteSecurityAdapter { - /** */ - static final byte SECURITY_CONTEXT_ATTRIBUTE_ID = 0; - /** */ private static final String FAILED_OBTAIN_SEC_CTX_MSG = "Failed to obtain a security context."; @@ -187,17 +185,34 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP @Override public SecurityContext securityContext() { SecurityContextMessage secCtxMsg = OperationContext.get(SEC_CTX_ATTR); - if (secCtxMsg != null) { - if (secCtxMsg.delegate() == null) { - try (Scope ignored = withContext(secCtxMsg.subjId)) { - return securityContext(); - } + if (secCtxMsg == null) + return dfltSecCtx; + + if (secCtxMsg.delegate() == null) + secCtxMsg.delegate(resolveSecurityContext(secCtxMsg.subjId)); + + return secCtxMsg.delegate(); + } + + /** */ + private SecurityContext resolveSecurityContext(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 secCtxMsg.delegate(); + return res; } + catch (Throwable e) { + log.error(FAILED_OBTAIN_SEC_CTX_MSG, e); - return dfltSecCtx; + throw e; + } } /** {@inheritDoc} */ @@ -254,7 +269,8 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP @Override public void start() throws IgniteCheckedException { super.start(); - ctx.operationContextDispatcher().registerDistributedAttribute(SECURITY_CONTEXT_ATTRIBUTE_ID, SEC_CTX_ATTR); + ctx.operationContextDispatcher().registerDistributedAttribute(DistributedOperationContextAttributes.SECURITY.id(), + SEC_CTX_ATTR); ctx.addNodeAttribute(ATTR_GRID_SEC_PROC_CLASS, secPrc.getClass().getName()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java index 13eb1c9023ddd..30010a03382d5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java @@ -51,4 +51,9 @@ public SecurityContextMessage(SecurityContext delegate) { 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/DistributedOperationContextAttributes.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java new file mode 100644 index 0000000000000..e044fb3bd727a --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** */ +public enum DistributedOperationContextAttributes { + /** Distributed {@link SecurityContext}. */ + SECURITY; + + /** Cluster-wide id of distributed attribute. */ + public byte id() { + return (byte)ordinal(); + } +} 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 6be6eeb4abaf7..44a272821bb5f 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,25 +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.OperationContextMessage; -import org.apache.ignite.internal.managers.GridManagerAdapter; -import org.apache.ignite.internal.managers.communication.GridIoMessage; import org.apache.ignite.internal.processors.security.impl.TestSecurityContext; import org.apache.ignite.internal.processors.security.impl.TestSecuritySubject; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; +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}. @@ -64,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) @@ -80,17 +68,11 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex listeningLog.registerListener(logPattern); - GridIoMessage msg = cli.context().io().createGridIoMessage(TOPIC_CACHE, new IgniteDiagnosticRequest(), PUBLIC_POOL, - false, 0, false); - - msg.opCtxMsg = new OperationContextMessage(); - - msg.opCtxMsg.vals = new Message[]{new SecurityContextMessage(new TestSecurityContext(new TestSecuritySubject() - .setId(UUID.randomUUID())))}; - - msg.opCtxMsg.idBitmap = 1 << IgniteSecurityProcessor.SECURITY_CONTEXT_ATTRIBUTE_ID; + TestSecurityContext unknownCtx = new TestSecurityContext(new TestSecuritySubject().setId(UUID.randomUUID())); - spi.sendMessage(srv.localNode(), msg); + 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()); } From dd57b8106128c52f6082b71cb5449173525d6a59 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 15:05:40 +0300 Subject: [PATCH 14/24] fix --- .../internal/processors/security/IgniteSecurityProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 eb70adad1525f..606f27abfe9af 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 @@ -141,7 +141,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP SecurityContext res = secPrc.securityContext(subjId); if (res == null) { - res = findNodeSecurityContext(subjId); + res = resolveSecurityContext(subjId); if (res == null) throw new IllegalStateException("Failed to find security context for subject with given ID : " + subjId); From 1d9421214e0f4b1d60dbe6d0443c491e0445672e Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 15:15:01 +0300 Subject: [PATCH 15/24] renaming, fix --- .../security/IgniteSecurityProcessor.java | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) 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 606f27abfe9af..0ceec21f4544a 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 @@ -137,23 +137,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public Scope withContext(UUID subjId) { - try { - SecurityContext res = secPrc.securityContext(subjId); - - if (res == null) { - res = resolveSecurityContext(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)); } /** @@ -189,13 +173,13 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP return dfltSecCtx; if (secCtxMsg.delegate() == null) - secCtxMsg.delegate(resolveSecurityContext(secCtxMsg.subjId)); + secCtxMsg.delegate(securityContext(secCtxMsg.subjId)); return secCtxMsg.delegate(); } /** */ - private SecurityContext resolveSecurityContext(UUID subjId) { + private SecurityContext securityContext(UUID subjId) { try { SecurityContext res = secPrc.securityContext(subjId); From d9fd00ba54c19343d052f4d45410c8f380f17efc Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 15:15:01 +0300 Subject: [PATCH 16/24] renaming, fix --- .../security/IgniteSecurityProcessor.java | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) 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 606f27abfe9af..0ceec21f4544a 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 @@ -137,23 +137,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public Scope withContext(UUID subjId) { - try { - SecurityContext res = secPrc.securityContext(subjId); - - if (res == null) { - res = resolveSecurityContext(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)); } /** @@ -189,13 +173,13 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP return dfltSecCtx; if (secCtxMsg.delegate() == null) - secCtxMsg.delegate(resolveSecurityContext(secCtxMsg.subjId)); + secCtxMsg.delegate(securityContext(secCtxMsg.subjId)); return secCtxMsg.delegate(); } /** */ - private SecurityContext resolveSecurityContext(UUID subjId) { + private SecurityContext securityContext(UUID subjId) { try { SecurityContext res = secPrc.securityContext(subjId); From 136f1f7b0fb3786488b9102120c7f81ee1717545 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 15:24:39 +0300 Subject: [PATCH 17/24] renaming, fix --- .../java/org/apache/ignite/internal/CoreMessagesProvider.java | 1 - 1 file changed, 1 deletion(-) 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 1fc9f8f127102..bab58f0c6d1ed 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 @@ -615,7 +615,6 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(GridIoMessage.class); withNoSchema(IgniteIoTestMessage.class); withSchema(GridIoUserMessage.class); - ++msgIdx; // Former GridIoSecurityAwareMessage withNoSchema(RecoveryLastReceivedMessage.class); withNoSchema(TcpInverseConnectionResponseMessage.class); withNoSchema(SessionChannelMessage.class); From a499dd837081f185f30d5ede9f1704f157211d8c Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 15:49:49 +0300 Subject: [PATCH 18/24] renaming --- .../org/apache/ignite/internal/CoreMessagesProvider.java | 4 ++-- .../processors/security/IgniteSecurityProcessor.java | 6 +++--- ...ityContextMessage.java => SecurityContextWrapper.java} | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) rename modules/core/src/main/java/org/apache/ignite/internal/processors/security/{SecurityContextMessage.java => SecurityContextWrapper.java} (87%) 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 bab58f0c6d1ed..e037bd50f020b 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 @@ -239,7 +239,7 @@ 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.SecurityContextMessage; +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; @@ -691,7 +691,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13500]: Operation context messages. msgIdx = 13400; withNoSchema(OperationContextMessage.class); - withNoSchema(SecurityContextMessage.class); + withNoSchema(SecurityContextWrapper.class); // [13600 - 13700]: Rolling Upgrade messages. msgIdx = 13600; 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 0ceec21f4544a..c07f7fd5b4c0a 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 @@ -95,7 +95,7 @@ static boolean hasSandboxedNodes() { * * @see OperationContextDispatcher */ - private static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); + private static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); /** Security processor. */ private final GridSecurityProcessor secPrc; @@ -132,7 +132,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public Scope withContext(SecurityContext secCtx) { - return OperationContext.set(SEC_CTX_ATTR, secCtx == dfltSecCtx ? null : new SecurityContextMessage(secCtx)); + return OperationContext.set(SEC_CTX_ATTR, secCtx == dfltSecCtx ? null : new SecurityContextWrapper(secCtx)); } /** {@inheritDoc} */ @@ -167,7 +167,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public SecurityContext securityContext() { - SecurityContextMessage secCtxMsg = OperationContext.get(SEC_CTX_ATTR); + SecurityContextWrapper secCtxMsg = OperationContext.get(SEC_CTX_ATTR); if (secCtxMsg == null) return dfltSecCtx; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextWrapper.java similarity index 87% rename from modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java rename to modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextWrapper.java index 30010a03382d5..0f330489fcbfe 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextWrapper.java @@ -24,11 +24,11 @@ import org.apache.ignite.plugin.security.SecuritySubject; /** - * Transfer for {@link SecurityContext}, id of {@link SecuritySubject}. + * Hollder and message for {@link SecurityContext}, id of {@link SecuritySubject}. * * @see OperationContextDispatcher#collectDistributedAttributes() */ -public class SecurityContextMessage implements Message { +public class SecurityContextWrapper implements Message { /** A value of {@link SecuritySubject#id()} */ @Order(0) UUID subjId; @@ -37,12 +37,12 @@ public class SecurityContextMessage implements Message { private SecurityContext delegate; /** Empty constructor for serialization purposes. */ - public SecurityContextMessage() { + public SecurityContextWrapper() { // No-op. } /** */ - public SecurityContextMessage(SecurityContext delegate) { + public SecurityContextWrapper(SecurityContext delegate) { this.delegate = delegate; this.subjId = delegate.subject().id(); } From 075b120f38703af6e49a89bbd7f446a7ba77519e Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 15:54:39 +0300 Subject: [PATCH 19/24] minority --- .../processors/security/SecurityContextWrapper.java | 4 +++- .../context/DistributedOperationContextAttributes.java | 9 +++++++-- .../thread/context/OperationContextDispatcher.java | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) 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 index 0f330489fcbfe..48459bfefe39a 100644 --- 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 @@ -19,14 +19,16 @@ import java.util.UUID; import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributes; import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.security.SecuritySubject; /** - * Hollder and message for {@link SecurityContext}, id of {@link SecuritySubject}. + * {@link SecurityContext} attribute value holder and message for {@link SecuritySubject}'s id. * * @see OperationContextDispatcher#collectDistributedAttributes() + * @see DistributedOperationContextAttributes#SECURITY */ public class SecurityContextWrapper implements Message { /** A value of {@link SecuritySubject#id()} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java index e044fb3bd727a..736c68daa08ca 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java @@ -18,10 +18,15 @@ 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 DistributedOperationContextAttributes { - /** Distributed {@link SecurityContext}. */ + /** + * Distributed {@link SecurityContext}. + * + * @see SecurityContextWrapper + */ SECURITY; /** Cluster-wide id of distributed attribute. */ 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 a066928657694..54c460035f9bf 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 @@ * * @see OperationContext * @see OperationContextMessage + * @see DistributedOperationContextAttributes */ public class OperationContextDispatcher { /** Maximal number of supported distributed attributes. */ From 278ddae051578d62960555e340ef5f72c4306f8c Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 15:59:50 +0300 Subject: [PATCH 20/24] minority --- .../processors/security/IgniteSecurityProcessor.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 c07f7fd5b4c0a..0ef2c3c29a220 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 @@ -167,15 +167,15 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public SecurityContext securityContext() { - SecurityContextWrapper secCtxMsg = OperationContext.get(SEC_CTX_ATTR); + SecurityContextWrapper secCtx = OperationContext.get(SEC_CTX_ATTR); - if (secCtxMsg == null) + if (secCtx == null) return dfltSecCtx; - if (secCtxMsg.delegate() == null) - secCtxMsg.delegate(securityContext(secCtxMsg.subjId)); + if (secCtx.delegate() == null) + secCtx.delegate(securityContext(secCtx.subjId)); - return secCtxMsg.delegate(); + return secCtx.delegate(); } /** */ From eb3094df7db321130af29ba867e440d78080fe93 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 16:22:10 +0300 Subject: [PATCH 21/24] minor renaming --- .../ignite/internal/managers/communication/GridIoManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 11d1649c85cf7..20a8af207f9a1 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 @@ -1829,7 +1829,7 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj if (change) CUR_PLC.set(plc); - try (Scope ignored = attachNodeSecurityContextIfRequired(nodeId)) { + try (Scope ignored = actualSecurityContext(nodeId)) { lsnr.onMessage(nodeId, msg, plc); } finally { @@ -1839,7 +1839,7 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj } /** */ - private Scope attachNodeSecurityContextIfRequired(UUID nodeId) { + private Scope actualSecurityContext(UUID nodeId) { if (ctx.security().isDefaultContext()) return ctx.security().withContext(nodeId); From a380d27c22521b65120050f483f10a37c0dfae6d Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 22:25:09 +0300 Subject: [PATCH 22/24] review fixes --- .../internal/managers/communication/GridIoManager.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 20a8af207f9a1..08befbe25008a 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 @@ -1829,7 +1829,7 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj if (change) CUR_PLC.set(plc); - try (Scope ignored = actualSecurityContext(nodeId)) { + try (Scope ignored = withRemoteSecurityContext(nodeId)) { lsnr.onMessage(nodeId, msg, plc); } finally { @@ -1839,11 +1839,13 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj } /** */ - private Scope actualSecurityContext(UUID nodeId) { + 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); - // Check that security context is valid. + // Verify that the Security Context currently attached to the thread is valid. ctx.security().securityContext(); return Scope.NOOP_SCOPE; From 81af6dc7b4b219ca318b18bc9b7bbca8f8c3cc7a Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 2 Jul 2026 22:49:52 +0300 Subject: [PATCH 23/24] review fixes --- .../internal/processors/security/IgniteSecurityProcessor.java | 4 ++-- .../internal/processors/security/SecurityContextWrapper.java | 4 ++-- ...ributes.java => DistributedOperationContextAttribute.java} | 2 +- .../internal/thread/context/OperationContextDispatcher.java | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename modules/core/src/main/java/org/apache/ignite/internal/thread/context/{DistributedOperationContextAttributes.java => DistributedOperationContextAttribute.java} (96%) 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 0ef2c3c29a220..d89f30d159666 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 @@ -32,7 +32,7 @@ import org.apache.ignite.internal.processors.security.sandbox.AccessControllerSandbox; 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.DistributedOperationContextAttributes; +import org.apache.ignite.internal.thread.context.DistributedOperationContextAttribute; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.thread.context.OperationContextDispatcher; @@ -253,7 +253,7 @@ private SecurityContext securityContext(UUID subjId) { @Override public void start() throws IgniteCheckedException { super.start(); - ctx.operationContextDispatcher().registerDistributedAttribute(DistributedOperationContextAttributes.SECURITY.id(), + ctx.operationContextDispatcher().registerDistributedAttribute(DistributedOperationContextAttribute.SECURITY.id(), SEC_CTX_ATTR); ctx.addNodeAttribute(ATTR_GRID_SEC_PROC_CLASS, secPrc.getClass().getName()); 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 index 48459bfefe39a..81777e5629fc2 100644 --- 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 @@ -19,7 +19,7 @@ import java.util.UUID; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributes; +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; @@ -28,7 +28,7 @@ * {@link SecurityContext} attribute value holder and message for {@link SecuritySubject}'s id. * * @see OperationContextDispatcher#collectDistributedAttributes() - * @see DistributedOperationContextAttributes#SECURITY + * @see DistributedOperationContextAttribute#SECURITY */ public class SecurityContextWrapper implements Message { /** A value of {@link SecuritySubject#id()} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttribute.java similarity index 96% rename from modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java rename to modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttribute.java index 736c68daa08ca..7c6899fec0eb7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributes.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttribute.java @@ -21,7 +21,7 @@ import org.apache.ignite.internal.processors.security.SecurityContextWrapper; /** Ids of Ignite's known distributed operation context attributes. */ -public enum DistributedOperationContextAttributes { +public enum DistributedOperationContextAttribute { /** * Distributed {@link SecurityContext}. * 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 54c460035f9bf..11f56e032bf6d 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,7 +44,7 @@ * * @see OperationContext * @see OperationContextMessage - * @see DistributedOperationContextAttributes + * @see DistributedOperationContextAttribute */ public class OperationContextDispatcher { /** Maximal number of supported distributed attributes. */ From 8299333358c8627b65620a3c1cbac761f52e3c5c Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 3 Jul 2026 15:39:44 +0300 Subject: [PATCH 24/24] review fix --- .../processors/security/IgniteSecurityProcessor.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 d89f30d159666..ddbf0d3d96f7a 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 @@ -32,7 +32,6 @@ import org.apache.ignite.internal.processors.security.sandbox.AccessControllerSandbox; 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.DistributedOperationContextAttribute; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.thread.context.OperationContextDispatcher; @@ -57,6 +56,7 @@ 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; @@ -253,8 +253,7 @@ private SecurityContext securityContext(UUID subjId) { @Override public void start() throws IgniteCheckedException { super.start(); - ctx.operationContextDispatcher().registerDistributedAttribute(DistributedOperationContextAttribute.SECURITY.id(), - SEC_CTX_ATTR); + ctx.operationContextDispatcher().registerDistributedAttribute(SECURITY.id(), SEC_CTX_ATTR); ctx.addNodeAttribute(ATTR_GRID_SEC_PROC_CLASS, secPrc.getClass().getName());