You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2018/04/17 04:47:00 UTC
ignite git commit: IGNITE-8201 REST: Added AUTHENTICATE command.
Fixed session tokens. Added new tests.
Repository: ignite
Updated Branches:
refs/heads/master 737933e6d -> 1cfc9897f
IGNITE-8201 REST: Added AUTHENTICATE command. Fixed session tokens. Added new tests.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1cfc9897
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1cfc9897
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1cfc9897
Branch: refs/heads/master
Commit: 1cfc9897f41e8d8b48510029e7b650b2ed699c9a
Parents: 737933e
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Apr 17 11:46:45 2018 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Apr 17 11:46:45 2018 +0700
----------------------------------------------------------------------
.../client/suite/IgniteClientTestSuite.java | 6 +-
.../JettyRestProcessorAbstractSelfTest.java | 60 ++++++++++-----
...ettyRestProcessorAuthenticationSelfTest.java | 45 ++---------
...rocessorAuthenticationWithCredsSelfTest.java | 32 ++++++++
...rocessorAuthenticationWithTokenSelfTest.java | 80 ++++++++++++++++++++
.../processors/rest/GridRestCommand.java | 3 +
.../processors/rest/GridRestProcessor.java | 26 ++++---
.../auth/AuthenticationCommandHandler.java | 70 +++++++++++++++++
.../rest/handlers/auth/package-info.java | 22 ++++++
.../http/jetty/GridJettyRestHandler.java | 55 +++++++++++---
10 files changed, 322 insertions(+), 77 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
index 79fcf38..163f89a 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
@@ -49,7 +49,8 @@ import org.apache.ignite.internal.client.util.ClientByteUtilsTest;
import org.apache.ignite.internal.client.util.ClientConsistentHashSelfTest;
import org.apache.ignite.internal.client.util.ClientJavaHasherSelfTest;
import org.apache.ignite.internal.processors.rest.ClientMemcachedProtocolSelfTest;
-import org.apache.ignite.internal.processors.rest.JettyRestProcessorAuthenticationSelfTest;
+import org.apache.ignite.internal.processors.rest.JettyRestProcessorAuthenticationWithCredsSelfTest;
+import org.apache.ignite.internal.processors.rest.JettyRestProcessorAuthenticationWithTokenSelfTest;
import org.apache.ignite.internal.processors.rest.JettyRestProcessorSignedSelfTest;
import org.apache.ignite.internal.processors.rest.JettyRestProcessorUnsignedSelfTest;
import org.apache.ignite.internal.processors.rest.RestBinaryProtocolSelfTest;
@@ -87,7 +88,8 @@ public class IgniteClientTestSuite extends TestSuite {
// Test jetty rest processor
suite.addTestSuite(JettyRestProcessorSignedSelfTest.class);
suite.addTestSuite(JettyRestProcessorUnsignedSelfTest.class);
- suite.addTestSuite(JettyRestProcessorAuthenticationSelfTest.class);
+ suite.addTestSuite(JettyRestProcessorAuthenticationWithCredsSelfTest.class);
+ suite.addTestSuite(JettyRestProcessorAuthenticationWithTokenSelfTest.class);
// Test TCP rest processor with original memcache client.
suite.addTestSuite(ClientMemcachedProtocolSelfTest.class);
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
index 5dc44c4..e36447b 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
@@ -294,14 +294,19 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
/**
* @param content Content to check.
+ * @return JSON node with actual response.
*/
- private JsonNode jsonCacheOperationResponse(String content, boolean bulk) throws IOException {
+ protected JsonNode assertResponseSucceeded(String content, boolean bulk) throws IOException {
assertNotNull(content);
assertFalse(content.isEmpty());
JsonNode node = JSON_MAPPER.readTree(content);
- assertEquals(bulk, node.get("affinityNodeId").isNull());
+ JsonNode affNode = node.get("affinityNodeId");
+
+ if (affNode != null)
+ assertEquals(bulk, affNode.isNull());
+
assertEquals(STATUS_SUCCESS, node.get("successStatus").asInt());
assertTrue(node.get("error").isNull());
@@ -315,7 +320,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
* @param res Response.
*/
private void assertCacheOperation(String content, Object res) throws IOException {
- JsonNode ret = jsonCacheOperationResponse(content, false);
+ JsonNode ret = assertResponseSucceeded(content, false);
assertEquals(String.valueOf(res), ret.isObject() ? ret.toString() : ret.asText());
}
@@ -325,7 +330,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
* @param res Response.
*/
private void assertCacheBulkOperation(String content, Object res) throws IOException {
- JsonNode ret = jsonCacheOperationResponse(content, true);
+ JsonNode ret = assertResponseSucceeded(content, true);
assertEquals(String.valueOf(res), ret.asText());
}
@@ -334,7 +339,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
* @param content Content to check.
*/
private void assertCacheMetrics(String content) throws IOException {
- JsonNode ret = jsonCacheOperationResponse(content, true);
+ JsonNode ret = assertResponseSucceeded(content, true);
assertTrue(ret.isObject());
}
@@ -349,7 +354,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
JsonNode node = JSON_MAPPER.readTree(content);
- assertEquals(0, node.get("successStatus").asInt());
+ assertEquals(STATUS_SUCCESS, node.get("successStatus").asInt());
assertTrue(node.get("error").isNull());
assertNotSame(securityEnabled(), node.get("sessionToken").isNull());
@@ -367,7 +372,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
JsonNode node = JSON_MAPPER.readTree(content);
- assertEquals(0, node.get("successStatus").asInt());
+ assertEquals(STATUS_SUCCESS, node.get("successStatus").asInt());
assertTrue(node.get("error").isNull());
assertFalse(node.get("response").isNull());
@@ -403,7 +408,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
* @throws IOException If failed.
*/
private void checkJson(String json, Person p) throws IOException {
- JsonNode res = jsonCacheOperationResponse(json, false);
+ JsonNode res = assertResponseSucceeded(json, false);
assertEquals(p.id.intValue(), res.get("id").asInt());
assertEquals(p.getOrganizationId().intValue(), res.get("orgId").asInt());
@@ -455,7 +460,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
info("Get command result: " + ret);
- JsonNode res = jsonCacheOperationResponse(ret, false);
+ JsonNode res = assertResponseSucceeded(ret, false);
assertEquals("Alex", res.get("NAME").asText());
assertEquals(300, res.get("SALARY").asInt());
@@ -476,7 +481,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
info("Get command result: " + ret);
- JsonNode json = jsonCacheOperationResponse(ret, false);
+ JsonNode json = assertResponseSucceeded(ret, false);
assertEquals(ref1.name, json.get("name").asText());
ref2.ref(ref1);
@@ -552,7 +557,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
info("Get command result: " + ret);
- JsonNode res = jsonCacheOperationResponse(ret, false);
+ JsonNode res = assertResponseSucceeded(ret, false);
assertEquals(p.id, res.get("id").asInt());
assertEquals(p.name, res.get("name").asText());
@@ -637,7 +642,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
info("Get command result: " + ret);
- JsonNode res = jsonCacheOperationResponse(ret, false);
+ JsonNode res = assertResponseSucceeded(ret, false);
assertEquals(t.getKey(), res.get("key").asText());
assertEquals(t.getValue(), res.get("value").asText());
@@ -775,11 +780,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
info("Get all command result: " + ret);
- JsonNode res = jsonCacheOperationResponse(ret, true);
+ JsonNode res = assertResponseSucceeded(ret, true);
assertTrue(res.isObject());
- assertTrue(entries.equals(JSON_MAPPER.treeToValue(res, Map.class)));
+ assertEquals(entries, JSON_MAPPER.treeToValue(res, Map.class));
}
/**
@@ -973,10 +978,25 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
assertCacheOperation(ret, true);
}
+ /** */
+ private void failIgnite_5874() {
+ DataStorageConfiguration dsCfg = ignite(0).configuration().getDataStorageConfiguration();
+
+ if (dsCfg.getDefaultDataRegionConfiguration().isPersistenceEnabled())
+ fail("IGNITE-5874");
+
+ for (DataRegionConfiguration dataRegCfg : dsCfg.getDataRegionConfigurations()) {
+ if (dataRegCfg.isPersistenceEnabled())
+ fail("IGNITE-5874");
+ }
+ }
+
/**
* @throws Exception If failed.
*/
public void testPutWithExpiration() throws Exception {
+ failIgnite_5874();
+
String ret = content(DEFAULT_CACHE_NAME, GridRestCommand.CACHE_PUT,
"key", "putKey",
"val", "putVal",
@@ -1013,6 +1033,8 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
* @throws Exception If failed.
*/
public void testAddWithExpiration() throws Exception {
+ failIgnite_5874();
+
String ret = content(DEFAULT_CACHE_NAME, GridRestCommand.CACHE_ADD,
"key", "addKey",
"val", "addVal",
@@ -1100,7 +1122,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
assertNull(jcache().localPeek("rmvKey2"));
assertNull(jcache().localPeek("rmvKey3"));
assertNull(jcache().localPeek("rmvKey4"));
- assertTrue(jcache().localSize() == 0);
+ assertEquals(0, jcache().localSize());
assertCacheBulkOperation(ret, true);
}
@@ -1152,6 +1174,8 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
* @throws Exception If failed.
*/
public void testReplaceWithExpiration() throws Exception {
+ failIgnite_5874();
+
jcache().put("replaceKey", "replaceVal");
assertEquals("replaceVal", jcache().get("replaceKey"));
@@ -1353,20 +1377,20 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
assertNotNull(keyClasses);
assertFalse(keyClasses.isNull());
- assertTrue(meta.keyClasses().equals(JSON_MAPPER.treeToValue(keyClasses, Map.class)));
+ assertEquals(meta.keyClasses(), JSON_MAPPER.treeToValue(keyClasses, Map.class));
JsonNode valClasses = item.get("valClasses");
assertNotNull(valClasses);
assertFalse(valClasses.isNull());
- assertTrue(meta.valClasses().equals(JSON_MAPPER.treeToValue(valClasses, Map.class)));
+ assertEquals(meta.valClasses(), JSON_MAPPER.treeToValue(valClasses, Map.class));
JsonNode fields = item.get("fields");
assertNotNull(fields);
assertFalse(fields.isNull());
- assertTrue(meta.fields().equals(JSON_MAPPER.treeToValue(fields, Map.class)));
+ assertEquals(meta.fields(), JSON_MAPPER.treeToValue(fields, Map.class));
JsonNode indexesByType = item.get("indexes");
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java
index ca62091..27b8c03 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java
@@ -24,7 +24,6 @@ import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.processors.authentication.IgniteAccessControlException;
import org.apache.ignite.internal.processors.authentication.IgniteAuthenticationProcessor;
-import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.testframework.GridTestUtils;
@@ -33,18 +32,12 @@ import static org.apache.ignite.configuration.WALMode.NONE;
/**
* Test REST with enabled authentication.
*/
-public class JettyRestProcessorAuthenticationSelfTest extends JettyRestProcessorUnsignedSelfTest {
+public abstract class JettyRestProcessorAuthenticationSelfTest extends JettyRestProcessorUnsignedSelfTest {
/** */
- private static final String DFLT_LOGIN = "ignite";
+ protected static final String DFLT_USER = "ignite";
/** */
- private static final String DFLT_PWD = "ignite";
-
- /** */
- private String login = DFLT_LOGIN;
-
- /** */
- private String pwd = DFLT_PWD;
+ protected static final String DFLT_PWD = "ignite";
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
@@ -54,11 +47,8 @@ public class JettyRestProcessorAuthenticationSelfTest extends JettyRestProcessor
}
/** {@inheritDoc} */
- @Override protected void beforeTest() throws Exception {
- super.beforeTest();
-
- login = DFLT_LOGIN;
- pwd = DFLT_PWD;
+ @Override protected boolean securityEnabled() {
+ return true;
}
/** {@inheritDoc} */
@@ -97,32 +87,13 @@ public class JettyRestProcessorAuthenticationSelfTest extends JettyRestProcessor
return cfg;
}
- /** {@inheritDoc} */
- @Override protected String restUrl() {
- String url = super.restUrl();
-
- if (!F.isEmpty(login)) {
- url += "ignite.login=" + login;
-
- if (!F.isEmpty(pwd))
- url += "&ignite.password=" + pwd;
-
- url += '&';
- }
-
- return url;
- }
-
/**
* @throws Exception If failed.
*/
- public void testMissingCredentials() throws Exception {
- login = null;
- pwd = null;
-
- String ret = content(null, GridRestCommand.VERSION);
+ public void testAuthenticationCommand() throws Exception {
+ String ret = content(null, GridRestCommand.AUTHENTICATE);
- assertResponseContainsError(ret, "The user name or password is incorrect");
+ assertResponseSucceeded(ret, false);
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationWithCredsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationWithCredsSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationWithCredsSelfTest.java
new file mode 100644
index 0000000..c75e8a9
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationWithCredsSelfTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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.rest;
+
+/**
+ * Test REST with enabled authentication and credentials in each request.
+ */
+public class JettyRestProcessorAuthenticationWithCredsSelfTest extends JettyRestProcessorAuthenticationSelfTest {
+ /** {@inheritDoc} */
+ @Override protected String restUrl() {
+ String url = super.restUrl();
+
+ url += "ignite.login=" + DFLT_USER + "&ignite.password=" + DFLT_PWD + "&";
+
+ return url;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationWithTokenSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationWithTokenSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationWithTokenSelfTest.java
new file mode 100644
index 0000000..5c046af
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationWithTokenSelfTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.rest;
+
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Test REST with enabled authentication and token.
+ */
+public class JettyRestProcessorAuthenticationWithTokenSelfTest extends JettyRestProcessorAuthenticationSelfTest {
+ /** */
+ private String tok = "";
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ // Authenticate and extract token.
+ if (F.isEmpty(tok)) {
+ String ret = content(null, GridRestCommand.AUTHENTICATE,
+ "user", DFLT_USER,
+ "password", DFLT_PWD);
+
+ int p1 = ret.indexOf("sessionToken");
+ int p2 = ret.indexOf('"', p1 + 16);
+
+ tok = ret.substring(p1 + 15, p2);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected String restUrl() {
+ String url = super.restUrl();
+
+ if (!F.isEmpty(tok))
+ url += "sessionToken=" + tok + "&";
+
+ return url;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testInvalidSessionToken() throws Exception {
+ tok = null;
+
+ String ret = content(null, GridRestCommand.VERSION);
+
+ assertResponseContainsError(ret, "Failed to handle request - session token not found or invalid");
+
+ tok = "InvalidToken";
+
+ ret = content(null, GridRestCommand.VERSION);
+
+ assertResponseContainsError(ret, "Failed to handle request - session token not found or invalid");
+
+ tok = "26BE027D32CC42329DEC92D517B44E9E";
+
+ ret = content(null, GridRestCommand.VERSION);
+
+ assertResponseContainsError(ret, "Failed to handle request - unknown session token (maybe expired session)");
+
+ tok = null; // Cleanup token for next tests.
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
index 0b9a662..265fe40 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
@@ -169,6 +169,9 @@ public enum GridRestCommand {
CLUSTER_CURRENT_STATE("currentstate"),
/** */
+ AUTHENTICATE("authenticate"),
+
+ /** */
ADD_USER("adduser"),
/** */
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
----------------------------------------------------------------------
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 4b8497e..da5e5c2 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
@@ -45,6 +45,7 @@ import org.apache.ignite.internal.processors.GridProcessorAdapter;
import org.apache.ignite.internal.processors.authentication.AuthorizationContext;
import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskResultBean;
import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandler;
+import org.apache.ignite.internal.processors.rest.handlers.auth.AuthenticationCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.cluster.GridChangeStateCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.datastructures.DataStructuresCommandHandler;
@@ -81,6 +82,7 @@ import org.apache.ignite.plugin.security.SecurityPermission;
import org.apache.ignite.thread.IgniteThread;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_REST_START_ON_CLIENT;
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.AUTHENTICATE;
import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_AUTH_FAILED;
import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_FAILED;
import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_SECURITY_CHECK_FAILED;
@@ -230,10 +232,11 @@ public class GridRestProcessor extends GridProcessorAdapter {
try {
ses = session(req);
}
+ catch (IgniteAuthenticationException e) {
+ return new GridFinishedFuture<>(new GridRestResponse(STATUS_AUTH_FAILED, e.getMessage()));
+ }
catch (IgniteCheckedException e) {
- GridRestResponse res = new GridRestResponse(STATUS_FAILED, e.getMessage());
-
- return new GridFinishedFuture<>(res);
+ return new GridFinishedFuture<>(new GridRestResponse(STATUS_FAILED, e.getMessage()));
}
assert ses != null;
@@ -284,9 +287,9 @@ public class GridRestProcessor extends GridProcessorAdapter {
throw new IgniteAuthenticationException("The user name or password is incorrect");
ses.authCtx = ctx.authentication().authenticate(login, pwd);
-
- req.authorizationContext(ses.authCtx);
}
+
+ req.authorizationContext(ses.authCtx);
}
catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(new GridRestResponse(STATUS_AUTH_FAILED, e.getMessage()));
@@ -341,7 +344,7 @@ public class GridRestProcessor extends GridProcessorAdapter {
assert res != null;
- if (ctx.security().enabled() && !failed)
+ if ((authenticationEnabled || securityEnabled) && !failed)
res.sessionTokenBytes(req.sessionToken());
interceptResponse(res, req);
@@ -362,6 +365,10 @@ public class GridRestProcessor extends GridProcessorAdapter {
while (true) {
if (F.isEmpty(sesTok) && clientId == null) {
+ // TODO: In IGNITE 3.0 we should check credentials only for AUTHENTICATE command.
+ if (ctx.authentication().enabled() && req.command() != AUTHENTICATE && req.credentials() == null)
+ throw new IgniteAuthenticationException("Failed to handle request - session token not found or invalid");
+
Session ses = Session.random();
UUID oldSesId = clientId2SesId.put(ses.clientId, ses.sesId);
@@ -451,10 +458,7 @@ public class GridRestProcessor extends GridProcessorAdapter {
try {
sesExpTime = System.getProperty(IgniteSystemProperties.IGNITE_REST_SESSION_TIMEOUT);
- if (sesExpTime != null)
- sesExpTime0 = Long.valueOf(sesExpTime) * 1000;
- else
- sesExpTime0 = DEFAULT_SES_TIMEOUT;
+ sesExpTime0 = sesExpTime != null ? Long.valueOf(sesExpTime) * 1000 : DEFAULT_SES_TIMEOUT;
}
catch (NumberFormatException ignore) {
U.warn(log, "Failed parsing IGNITE_REST_SESSION_TIMEOUT system variable [IGNITE_REST_SESSION_TIMEOUT="
@@ -504,6 +508,7 @@ public class GridRestProcessor extends GridProcessorAdapter {
addHandler(new QueryCommandHandler(ctx));
addHandler(new GridLogCommandHandler(ctx));
addHandler(new GridChangeStateCommandHandler(ctx));
+ addHandler(new AuthenticationCommandHandler(ctx));
addHandler(new UserActionCommandHandler(ctx));
// Start protocols.
@@ -860,6 +865,7 @@ public class GridRestProcessor extends GridProcessorAdapter {
case CLUSTER_CURRENT_STATE:
case CLUSTER_ACTIVE:
case CLUSTER_INACTIVE:
+ case AUTHENTICATE:
case ADD_USER:
case REMOVE_USER:
case UPDATE_USER:
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/auth/AuthenticationCommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/auth/AuthenticationCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/auth/AuthenticationCommandHandler.java
new file mode 100644
index 0000000..aa9bbbd
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/auth/AuthenticationCommandHandler.java
@@ -0,0 +1,70 @@
+/*
+ * 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.rest.handlers.auth;
+
+import java.util.Collection;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.processors.rest.GridRestCommand;
+import org.apache.ignite.internal.processors.rest.GridRestResponse;
+import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandlerAdapter;
+import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
+import org.apache.ignite.internal.util.future.GridFinishedFuture;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.AUTHENTICATE;
+
+/**
+ * Authentication handler.
+ */
+public class AuthenticationCommandHandler extends GridRestCommandHandlerAdapter {
+ /** Commands. */
+ private static final Collection<GridRestCommand> SUPPORTED_COMMANDS = U.sealList(AUTHENTICATE);
+
+ /**
+ * @param ctx Context.
+ */
+ public AuthenticationCommandHandler(GridKernalContext ctx) {
+ super(ctx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<GridRestCommand> supportedCommands() {
+ return SUPPORTED_COMMANDS;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteInternalFuture<GridRestResponse> handleAsync(GridRestRequest req) {
+ assert req != null;
+
+ if (log.isDebugEnabled())
+ log.debug("Handling topology REST request: " + req);
+
+ try {
+ if (log.isDebugEnabled())
+ log.debug("Handled topology REST request [req=" + req + ']');
+
+ return new GridFinishedFuture<>(new GridRestResponse(true));
+ }
+ catch (Throwable e) {
+ log.error("Failed to handle REST request [req=" + req + ']', e);
+
+ return new GridFinishedFuture<>(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/auth/package-info.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/auth/package-info.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/auth/package-info.java
new file mode 100644
index 0000000..1d58218
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/auth/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * REST authentication command.
+ */
+package org.apache.ignite.internal.processors.rest.handlers.auth;
http://git-wip-us.apache.org/repos/asf/ignite/blob/1cfc9897/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
index b3fbddd..99a8844 100644
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
+++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
@@ -86,6 +86,12 @@ public class GridJettyRestHandler extends AbstractHandler {
private static final String CHARSET = StandardCharsets.UTF_8.name();
/** */
+ private static final String USER_PARAM = "user";
+
+ /** */
+ private static final String PWD_PARAM = "password";
+
+ /** */
private static final String CACHE_NAME_PARAM = "cacheName";
/** */
@@ -100,10 +106,10 @@ public class GridJettyRestHandler extends AbstractHandler {
/** */
private static final String WRITE_SYNCHRONIZATION_MODE_PARAM = "writeSynchronizationMode";
- /** */
+ /**@deprecated Should be replaced with AUTHENTICATION + token in IGNITE 3.0 */
private static final String IGNITE_LOGIN = "ignite.login";
- /** */
+ /**@deprecated Should be replaced with AUTHENTICATION + token in IGNITE 3.0 */
private static final String IGNITE_PASSWORD = "ignite.password";
/** */
@@ -731,6 +737,12 @@ public class GridJettyRestHandler extends AbstractHandler {
break;
}
+ case AUTHENTICATE: {
+ restReq = new GridRestRequest();
+
+ break;
+ }
+
case ADD_USER:
case REMOVE_USER:
case UPDATE_USER: {
@@ -840,12 +852,9 @@ public class GridJettyRestHandler extends AbstractHandler {
restReq.command(cmd);
- if (params.containsKey(IGNITE_LOGIN) || params.containsKey(IGNITE_PASSWORD)) {
- SecurityCredentials cred = new SecurityCredentials(
- (String)params.get(IGNITE_LOGIN), (String)params.get(IGNITE_PASSWORD));
-
- restReq.credentials(cred);
- }
+ // TODO: In IGNITE 3.0 we should check credentials only for AUTHENTICATE command.
+ if (!credentials(params, IGNITE_LOGIN, IGNITE_PASSWORD, restReq))
+ credentials(params, USER_PARAM, PWD_PARAM, restReq);
String clientId = (String)params.get("clientId");
@@ -870,8 +879,13 @@ public class GridJettyRestHandler extends AbstractHandler {
String sesTokStr = (String)params.get("sessionToken");
try {
- if (sesTokStr != null)
- restReq.sessionToken(U.hexString2ByteArray(sesTokStr));
+ if (sesTokStr != null) {
+ // Token is a UUID encoded as 16 bytes as HEX.
+ byte[] bytes = U.hexString2ByteArray(sesTokStr);
+
+ if (bytes.length == 16)
+ restReq.sessionToken(bytes);
+ }
}
catch (IllegalArgumentException ignored) {
// Ignore invalid session token.
@@ -881,6 +895,27 @@ public class GridJettyRestHandler extends AbstractHandler {
}
/**
+ *
+ * @param params Parameters.
+ * @param userParam Parameter name to take user name.
+ * @param pwdParam Parameter name to take password.
+ * @param restReq Request to add credentials if any.
+ * @return {@code true} If params contains credentials.
+ */
+ private boolean credentials(Map<String, Object> params, String userParam, String pwdParam, GridRestRequest restReq) {
+ boolean hasCreds = params.containsKey(userParam) || params.containsKey(pwdParam);
+
+ if (hasCreds) {
+ SecurityCredentials cred = new SecurityCredentials((String)params.get(userParam),
+ (String)params.get(pwdParam));
+
+ restReq.credentials(cred);
+ }
+
+ return hasCreds;
+ }
+
+ /**
* Gets values referenced by sequential keys, e.g. {@code key1...keyN}.
*
* @param type Optional value type.