From 7e51cb90715dd6db8bd75cfa37551f92a74a3098 Mon Sep 17 00:00:00 2001 From: Mikhail Petrov <32207922+petrov-mg@users.noreply.github.com> Date: Fri, 15 Sep 2023 17:36:35 +0300 Subject: [PATCH] IGNITE-20421 Added Security Subject ID in GridRestResponse. (#10934) --- .../processors/rest/GridRestProcessor.java | 10 +++- .../processors/rest/GridRestResponse.java | 16 +++++++ .../rest/RestProcessorInitializationTest.java | 48 +++++++++++++++---- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index aaaa527c0eac6..0c521ceef9b73 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -320,6 +320,8 @@ private IgniteInternalFuture handleRequest0(GridRestRequest re GridRestCommandHandler hnd = handlers.get(req.command()); + final UUID secSubjId = securityEnabled ? ctx.security().securityContext().subject().id() : null; + if (hnd == null) { return new GridFinishedFuture<>( new IgniteCheckedException("Failed to find registered handler for command: " + req.command())); @@ -384,8 +386,12 @@ else if (X.hasCause(e, IllegalArgumentException.class)) { assert res != null; - if (securityEnabled && !failed) - res.sessionTokenBytes(req.sessionToken()); + if (securityEnabled) { + if (!failed) + res.sessionTokenBytes(req.sessionToken()); + + res.setSecuritySubjectId(secSubjId); + } interceptResponse(res, req); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestResponse.java index adefd9e641b32..f61511e7d7ada 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestResponse.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; +import java.util.UUID; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; @@ -67,6 +68,9 @@ public class GridRestResponse implements Externalizable { @GridToStringInclude(sensitive = true) private Object obj; + /** */ + private UUID secSubjId; + /** * */ @@ -160,6 +164,16 @@ public void setSessionToken(@Nullable String sesTokStr) { this.sesTokStr = sesTokStr; } + /** */ + public UUID getSecuritySubjectId() { + return secSubjId; + } + + /** */ + public void setSecuritySubjectId(UUID secSubjId) { + this.secSubjId = secSubjId; + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridRestResponse.class, this); @@ -172,6 +186,7 @@ public void setSessionToken(@Nullable String sesTokStr) { U.writeString(out, sesTokStr); U.writeString(out, err); out.writeObject(obj); + U.writeUuid(out, secSubjId); } /** {@inheritDoc} */ @@ -181,5 +196,6 @@ public void setSessionToken(@Nullable String sesTokStr) { sesTokStr = U.readString(in); err = U.readString(in); obj = in.readObject(); + secSubjId = U.readUuid(in); } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/RestProcessorInitializationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/RestProcessorInitializationTest.java index 6434f93e8ea26..2bc8793cc7540 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/RestProcessorInitializationTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/rest/RestProcessorInitializationTest.java @@ -23,18 +23,28 @@ import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.processors.rest.request.GridRestRequest; +import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest; +import org.apache.ignite.internal.processors.security.AbstractSecurityTest; +import org.apache.ignite.internal.processors.security.impl.TestSecurityData; +import org.apache.ignite.internal.processors.security.impl.TestSecurityPluginProvider; +import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.plugin.AbstractTestPluginProvider; import org.apache.ignite.plugin.PluginContext; import org.apache.ignite.plugin.PluginProvider; -import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.apache.ignite.plugin.security.SecurityCredentials; import org.jetbrains.annotations.Nullable; import org.junit.Test; +import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_SUCCESS; +import static org.apache.ignite.plugin.security.SecurityPermission.JOIN_AS_SERVER; +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.ALL_PERMISSIONS; +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.systemPermissions; + /** * Tests REST processor configuration via Ignite plugins functionality. */ -public class RestProcessorInitializationTest extends GridCommonAbstractTest { +public class RestProcessorInitializationTest extends AbstractSecurityTest { /** {@inheritDoc} */ @Override protected void afterTest() throws Exception { stopAllGrids(true); @@ -55,23 +65,22 @@ public void testDefaultRestProcessorInitialization() throws Exception { */ @Test public void testCustomRestProcessorInitialization() throws Exception { - IgniteConfiguration cfg = getConfiguration(getTestIgniteInstanceName(0)) - .setConnectorConfiguration(new ConnectorConfiguration()); - - cfg.setPluginProviders(new TestRestProcessorProvider()); - - IgniteEx ignite = startGrid(cfg); + IgniteEx ignite = startGrid(configuration(0)); assertEquals(ignite.context().rest().getClass(), TestGridRestProcessorImpl.class); TestGridRestProcessorImpl rest = (TestGridRestProcessorImpl)ignite.context().rest(); - GridRestRequest req = new GridRestRequest(); + GridRestTaskRequest req = new GridRestTaskRequest(); - req.command(GridRestCommand.VERSION); + req.credentials(new SecurityCredentials("client", "")); + req.command(GridRestCommand.NOOP); GridRestResponse res = rest.handleAsync0(req).get(); + assertEquals(STATUS_SUCCESS, res.getSuccessStatus()); + assertEquals(req.clientId(), res.getSecuritySubjectId()); + IgniteBiTuple> entry = rest.getTuple(); assertEquals(req, entry.get1()); @@ -124,4 +133,23 @@ public IgniteBiTuple> ge return tuple; } } + + /** */ + private IgniteConfiguration configuration(int idx) throws Exception { + String login = getTestIgniteInstanceName(idx); + + IgniteConfiguration cfg = getConfiguration( + login, + new TestSecurityPluginProvider( + login, + "", + systemPermissions(JOIN_AS_SERVER), + null, + false, + new TestSecurityData("client", ALL_PERMISSIONS))); + + return cfg + .setConnectorConfiguration(new ConnectorConfiguration()) + .setPluginProviders(F.concat(cfg.getPluginProviders(), new TestRestProcessorProvider())); + } }