IGNITE-8428 Web Console: Implemented connection to secured cluster.

Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c8be8c2b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c8be8c2b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c8be8c2b

Branch: refs/heads/ignite-8446
Commit: c8be8c2b8e8a474a90735d6e9eaebc67c1c8e3de
Parents: 523a871
Author: Alexey Kuznetsov <akuznet...@apache.org>
Authored: Fri Jun 22 17:00:11 2018 +0700
Committer: Alexey Kuznetsov <akuznet...@apache.org>
Committed: Fri Jun 22 17:00:11 2018 +0700

----------------------------------------------------------------------
 .../rest/AbstractRestProcessorSelfTest.java     |   4 +-
 .../JettyRestProcessorAbstractSelfTest.java     | 116 +------------
 .../rest/JettyRestProcessorCommonSelfTest.java  | 171 +++++++++++++++++++
 .../rest/JettyRestProcessorSignedSelfTest.java  |   6 +-
 .../JettyRestProcessorUnsignedSelfTest.java     |  11 +-
 .../apache/ignite/IgniteSystemProperties.java   |  13 +-
 .../processors/rest/GridRestProcessor.java      |  94 ++++++----
 .../visor/compute/VisorGatewayTask.java         |  11 +-
 .../security/SecurityBasicPermissionSet.java    |   4 +-
 9 files changed, 262 insertions(+), 168 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/AbstractRestProcessorSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/AbstractRestProcessorSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/AbstractRestProcessorSelfTest.java
index c67d735..3a8afa4 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/AbstractRestProcessorSelfTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/AbstractRestProcessorSelfTest.java
@@ -29,7 +29,7 @@ import 
org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 /**
  * Abstract class for REST protocols tests.
  */
-abstract class AbstractRestProcessorSelfTest extends GridCommonAbstractTest {
+public abstract class AbstractRestProcessorSelfTest extends 
GridCommonAbstractTest {
     /** IP finder. */
     private static final TcpDiscoveryIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
 
@@ -55,7 +55,7 @@ abstract class AbstractRestProcessorSelfTest extends 
GridCommonAbstractTest {
     @Override protected void afterTest() throws Exception {
         jcache().clear();
 
-        assertTrue(jcache().localSize() == 0);
+        assertEquals(0, jcache().localSize());
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/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 42f95db..25d5e89 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
@@ -18,13 +18,8 @@
 package org.apache.ignite.internal.processors.rest;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
 import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLConnection;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.sql.Date;
@@ -34,7 +29,6 @@ import java.text.DateFormat;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -42,7 +36,6 @@ import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
 
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheMode;
@@ -148,7 +141,6 @@ import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.testframework.GridTestUtils;
 
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT;
 import static org.apache.ignite.cache.CacheMode.PARTITIONED;
 import static org.apache.ignite.cache.CacheMode.REPLICATED;
 import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC;
@@ -163,118 +155,22 @@ import static 
org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS
  * Tests for Jetty REST protocol.
  */
 @SuppressWarnings("unchecked")
-public abstract class JettyRestProcessorAbstractSelfTest extends 
AbstractRestProcessorSelfTest {
-    /** Grid count. */
-    private static final int GRID_CNT = 3;
-
+public abstract class JettyRestProcessorAbstractSelfTest extends 
JettyRestProcessorCommonSelfTest {
     /** Used to sent request charset. */
     private static final String CHARSET = StandardCharsets.UTF_8.name();
 
-    /** JSON to java mapper. */
-    private static final ObjectMapper JSON_MAPPER = new 
GridJettyObjectMapper();
-
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
-        System.setProperty(IGNITE_JETTY_PORT, Integer.toString(restPort()));
-
         super.beforeTestsStarted();
 
         initCache();
     }
 
     /** {@inheritDoc} */
-    @Override protected void afterTestsStopped() throws Exception {
-        System.clearProperty(IGNITE_JETTY_PORT);
-    }
-
-    /** {@inheritDoc} */
     @Override protected void beforeTest() throws Exception {
         grid(0).cache(DEFAULT_CACHE_NAME).removeAll();
     }
 
-    /** {@inheritDoc} */
-    @Override protected int gridCount() {
-        return GRID_CNT;
-    }
-
-    /**
-     * @return Port to use for rest. Needs to be changed over time because 
Jetty has some delay before port unbind.
-     */
-    protected abstract int restPort();
-
-    /**
-     * @return Test URL
-     */
-    protected String restUrl() {
-        return "http://"; + LOC_HOST + ":" + restPort() + "/ignite?";
-    }
-
-    /**
-     * @return Security enabled flag. Should be the same with {@code 
ctx.security().enabled()}.
-     */
-    protected boolean securityEnabled() {
-        return false;
-    }
-
-    /**
-     * Execute REST command and return result.
-     *
-     * @param params Command parameters.
-     * @return Returned content.
-     * @throws Exception If failed.
-     */
-    protected String content(Map<String, String> params) throws Exception {
-        SB sb = new SB(restUrl());
-
-        for (Map.Entry<String, String> e : params.entrySet())
-            sb.a(e.getKey()).a('=').a(e.getValue()).a('&');
-
-        URL url = new URL(sb.toString());
-
-        URLConnection conn = url.openConnection();
-
-        String signature = signature();
-
-        if (signature != null)
-            conn.setRequestProperty("X-Signature", signature);
-
-        InputStream in = conn.getInputStream();
-
-        StringBuilder buf = new StringBuilder(256);
-
-        try (LineNumberReader rdr = new LineNumberReader(new 
InputStreamReader(in, "UTF-8"))) {
-            for (String line = rdr.readLine(); line != null; line = 
rdr.readLine())
-                buf.append(line);
-        }
-
-        return buf.toString();
-    }
-
-    /**
-     * @param cacheName Optional cache name.
-     * @param cmd REST command.
-     * @param params Command parameters.
-     * @return Returned content.
-     * @throws Exception If failed.
-     */
-    protected String content(String cacheName, GridRestCommand cmd, String... 
params) throws Exception {
-        Map<String, String> paramsMap = new LinkedHashMap<>();
-
-        if (cacheName != null)
-            paramsMap.put("cacheName", cacheName);
-
-        paramsMap.put("cmd", cmd.key());
-
-        if (params != null) {
-            assertEquals(0, params.length % 2);
-
-            for (int i = 0; i < params.length; i += 2)
-                paramsMap.put(params[i], params[i + 1]);
-        }
-
-        return content(paramsMap);
-    }
-
     /**
      * @param content Content to check.
      * @param err Error message.
@@ -1497,7 +1393,7 @@ public abstract class JettyRestProcessorAbstractSelfTest 
extends AbstractRestPro
 
         JsonNode res = jsonResponse(ret);
 
-        assertEquals(GRID_CNT, res.size());
+        assertEquals(gridCount(), res.size());
 
         for (JsonNode node : res) {
             assertTrue(node.get("attributes").isNull());
@@ -2603,18 +2499,12 @@ public abstract class 
JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     }
 
     /**
-     * @return Signature.
-     * @throws Exception If failed.
-     */
-    protected abstract String signature() throws Exception;
-
-    /**
      * @return True if any query cursor is available.
      */
     private boolean queryCursorFound() {
         boolean found = false;
 
-        for (int i = 0; i < GRID_CNT; ++i) {
+        for (int i = 0; i < gridCount(); ++i) {
             Map<GridRestCommand, GridRestCommandHandler> handlers =
                 GridTestUtils.getFieldValue(grid(i).context().rest(), 
"handlers");
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorCommonSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorCommonSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorCommonSelfTest.java
new file mode 100644
index 0000000..2076d49
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorCommonSelfTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import 
org.apache.ignite.internal.processors.rest.protocols.http.jetty.GridJettyObjectMapper;
+import org.apache.ignite.internal.util.typedef.internal.SB;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT;
+
+/**
+ * Base class for testing Jetty REST protocol.
+ */
+public abstract class JettyRestProcessorCommonSelfTest extends 
AbstractRestProcessorSelfTest {
+    /** Grid count. */
+    private static final int GRID_CNT = 3;
+
+    /** REST port. */
+    private static final int DFLT_REST_PORT = 8091;
+
+    /** JSON to java mapper. */
+    protected static final ObjectMapper JSON_MAPPER = new 
GridJettyObjectMapper();
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        System.setProperty(IGNITE_JETTY_PORT, Integer.toString(restPort()));
+
+        super.beforeTestsStarted();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        System.clearProperty(IGNITE_JETTY_PORT);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected int gridCount() {
+        return GRID_CNT;
+    }
+
+    /**
+     * @return Port to use for rest. Needs to be changed over time because 
Jetty has some delay before port unbind.
+     */
+    protected int restPort() {
+        return DFLT_REST_PORT;
+    }
+
+    /**
+     * @return Test URL
+     */
+    protected String restUrl() {
+        return "http://"; + LOC_HOST + ":" + restPort() + "/ignite?";
+    }
+
+    /**
+     * @return Security enabled flag. Should be the same with {@code 
ctx.security().enabled()}.
+     */
+    protected boolean securityEnabled() {
+        return false;
+    }
+
+    /**
+     * @return Signature.
+     * @throws Exception If failed.
+     */
+    protected abstract String signature() throws Exception;
+
+    /**
+     * Execute REST command and return result.
+     *
+     * @param params Command parameters.
+     * @return Returned content.
+     * @throws Exception If failed.
+     */
+    protected String content(Map<String, String> params) throws Exception {
+        SB sb = new SB(restUrl());
+
+        for (Map.Entry<String, String> e : params.entrySet())
+            sb.a(e.getKey()).a('=').a(e.getValue()).a('&');
+
+        URL url = new URL(sb.toString());
+
+        URLConnection conn = url.openConnection();
+
+        String signature = signature();
+
+        if (signature != null)
+            conn.setRequestProperty("X-Signature", signature);
+
+        InputStream in = conn.getInputStream();
+
+        StringBuilder buf = new StringBuilder(256);
+
+        try (LineNumberReader rdr = new LineNumberReader(new 
InputStreamReader(in, "UTF-8"))) {
+            for (String line = rdr.readLine(); line != null; line = 
rdr.readLine())
+                buf.append(line);
+        }
+
+        return buf.toString();
+    }
+
+    /**
+     * @param cacheName Optional cache name.
+     * @param cmd REST command.
+     * @param params Command parameters.
+     * @return Returned content.
+     * @throws Exception If failed.
+     */
+    protected String content(String cacheName, GridRestCommand cmd, String... 
params) throws Exception {
+        Map<String, String> paramsMap = new LinkedHashMap<>();
+
+        if (cacheName != null)
+            paramsMap.put("cacheName", cacheName);
+
+        paramsMap.put("cmd", cmd.key());
+
+        if (params != null) {
+            assertEquals(0, params.length % 2);
+
+            for (int i = 0; i < params.length; i += 2)
+                paramsMap.put(params[i], params[i + 1]);
+        }
+
+        return content(paramsMap);
+    }
+
+    /**
+     * @param json JSON content.
+     * @param field Field name in JSON object.
+     * @return Field value.
+     * @throws IOException If failed.
+     */
+    protected String jsonField(String json, String field) throws IOException {
+        assertNotNull(json);
+        assertFalse(json.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(json);
+
+        JsonNode fld = node.get(field);
+
+        assertNotNull(fld);
+
+        return fld.asText();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorSignedSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorSignedSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorSignedSelfTest.java
index 00e4c68..3be99b4 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorSignedSelfTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorSignedSelfTest.java
@@ -82,11 +82,11 @@ public class JettyRestProcessorSignedSelfTest extends 
JettyRestProcessorAbstract
     @Override protected String signature() throws Exception {
         long ts = U.currentTimeMillis();
 
-        String s = ts + ":" + REST_SECRET_KEY;
-
         try {
             MessageDigest md = MessageDigest.getInstance("SHA-1");
 
+            String s = ts + ":" + REST_SECRET_KEY;
+
             md.update(s.getBytes());
 
             String hash = Base64.getEncoder().encodeToString(md.digest());
@@ -97,4 +97,4 @@ public class JettyRestProcessorSignedSelfTest extends 
JettyRestProcessorAbstract
             throw new Exception("Failed to create authentication signature.", 
e);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorUnsignedSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorUnsignedSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorUnsignedSelfTest.java
index 988cedf..c7ff0d2 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorUnsignedSelfTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorUnsignedSelfTest.java
@@ -18,16 +18,11 @@
 package org.apache.ignite.internal.processors.rest;
 
 /**
- *
+ * Unsigned REST tests.
  */
 public class JettyRestProcessorUnsignedSelfTest extends 
JettyRestProcessorAbstractSelfTest {
     /** {@inheritDoc} */
-    @Override protected int restPort() {
-        return 8091;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected String signature() throws Exception {
+    @Override protected String signature() {
         return null;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java 
b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 9ff216b..70b35bf 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -118,9 +118,12 @@ public final class IgniteSystemProperties {
      */
     public static final String IGNITE_JETTY_LOG_NO_OVERRIDE = 
"IGNITE_JETTY_LOG_NO_OVERRIDE";
 
-    /** This property allow rewriting default ({@code 30}) rest session expire 
time (in seconds). */
+    /** This property allow rewriting default ({@code 30}) REST session expire 
time (in seconds). */
     public static final String IGNITE_REST_SESSION_TIMEOUT = 
"IGNITE_REST_SESSION_TIMEOUT";
 
+    /** This property allow rewriting default ({@code 300}) REST session 
security token expire time (in seconds). */
+    public static final String IGNITE_REST_SECURITY_TOKEN_TIMEOUT = 
"IGNITE_REST_SECURITY_TOKEN_TIMEOUT";
+
     /**
      * This property allows to override maximum count of task results stored 
on one node
      * in REST processor.
@@ -988,7 +991,7 @@ public final class IgniteSystemProperties {
      * The result is transformed to {@code int} using {@code 
Integer.parseInt()} method.
      *
      * @param name Name of the system property or environment variable.
-     * @param dflt Default value
+     * @param dflt Default value.
      * @return Integer value of the system property or environment variable.
      *         Returns default value in case neither system property
      *         nor environment variable with given name is found.
@@ -1016,7 +1019,7 @@ public final class IgniteSystemProperties {
      * The result is transformed to {@code float} using {@code 
Float.parseFloat()} method.
      *
      * @param name Name of the system property or environment variable.
-     * @param dflt Default value
+     * @param dflt Default value.
      * @return Float value of the system property or environment variable.
      *         Returns default value in case neither system property
      *         nor environment variable with given name is found.
@@ -1044,7 +1047,7 @@ public final class IgniteSystemProperties {
      * The result is transformed to {@code long} using {@code 
Long.parseLong()} method.
      *
      * @param name Name of the system property or environment variable.
-     * @param dflt Default value
+     * @param dflt Default value.
      * @return Integer value of the system property or environment variable.
      *         Returns default value in case neither system property
      *         nor environment variable with given name is found.
@@ -1072,7 +1075,7 @@ public final class IgniteSystemProperties {
      * The result is transformed to {@code double} using {@code 
Double.parseDouble()} method.
      *
      * @param name Name of the system property or environment variable.
-     * @param dflt Default value
+     * @param dflt Default value.
      * @return Integer value of the system property or environment variable.
      *         Returns default value in case neither system property
      *         nor environment variable with given name is found.

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/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 da5e5c2..d7a30f9 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
@@ -72,6 +72,7 @@ import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.util.worker.GridWorker;
 import org.apache.ignite.internal.util.worker.GridWorkerFuture;
+import org.apache.ignite.internal.visor.compute.VisorGatewayTask;
 import org.apache.ignite.internal.visor.util.VisorClusterGroupEmptyException;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteInClosure;
@@ -81,6 +82,8 @@ import org.apache.ignite.plugin.security.SecurityException;
 import org.apache.ignite.plugin.security.SecurityPermission;
 import org.apache.ignite.thread.IgniteThread;
 
+import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_REST_SECURITY_TOKEN_TIMEOUT;
+import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_REST_SESSION_TIMEOUT;
 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;
@@ -99,8 +102,14 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
     /** Delay between sessions timeout checks. */
     private static final int SES_TIMEOUT_CHECK_DELAY = 1_000;
 
-    /** Default session timout. */
-    private static final int DEFAULT_SES_TIMEOUT = 30_000;
+    /** Default session timeout, in seconds. */
+    private static final int DFLT_SES_TIMEOUT = 30;
+
+    /** The default interval used to invalidate sessions, in seconds. */
+    private static final int DFLT_SES_TOKEN_INVALIDATE_INTERVAL = 5 * 60;
+
+    /** Index of task name wrapped by VisorGatewayTask */
+    private static final int WRAPPED_TASK_IDX = 1;
 
     /** Protocols. */
     private final Collection<GridRestProtocol> protos = new ArrayList<>();
@@ -140,6 +149,9 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
     /** Session time to live. */
     private final long sesTtl;
 
+    /** Interval to invalidate session tokens. */
+    private final long sesTokTtl;
+
     /**
      * @param req Request.
      * @return Future.
@@ -252,8 +264,8 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
                 SecurityContext secCtx0 = ses.secCtx;
 
                 try {
-                    if (secCtx0 == null)
-                        ses.secCtx = secCtx0 = authenticate(req);
+                    if (secCtx0 == null || ses.isTokenExpired(sesTokTtl))
+                        ses.secCtx = secCtx0 = authenticate(req, ses);
 
                     authorize(req, secCtx0);
                 }
@@ -426,7 +438,7 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
                 UUID sesId = clientId2SesId.get(clientId);
 
                 if (sesId == null || !sesId.equals(U.bytesToUuid(sesTok, 0)))
-                    throw new IgniteCheckedException("Failed to handle request 
- unsupported case (misamatched " +
+                    throw new IgniteCheckedException("Failed to handle request 
- unsupported case (mismatched " +
                         "clientId and session token) [clientId=" + clientId + 
", sesTok=" +
                         U.byteArray2HexString(sesTok) + "]");
 
@@ -452,22 +464,8 @@ public class GridRestProcessor extends 
GridProcessorAdapter {
     public GridRestProcessor(GridKernalContext ctx) {
         super(ctx);
 
-        long sesExpTime0;
-        String sesExpTime = null;
-
-        try {
-            sesExpTime = 
System.getProperty(IgniteSystemProperties.IGNITE_REST_SESSION_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="
-                + sesExpTime + "]");
-
-            sesExpTime0 = DEFAULT_SES_TIMEOUT;
-        }
-
-        sesTtl = sesExpTime0;
+        sesTtl = IgniteSystemProperties.getLong(IGNITE_REST_SESSION_TIMEOUT, 
DFLT_SES_TIMEOUT) * 1000;
+        sesTokTtl = 
IgniteSystemProperties.getLong(IGNITE_REST_SECURITY_TOKEN_TIMEOUT, 
DFLT_SES_TOKEN_INVALIDATE_INTERVAL) * 100;
 
         sesTimeoutCheckerThread = new IgniteThread(ctx.igniteInstanceName(), 
"session-timeout-worker",
             new GridWorker(ctx.igniteInstanceName(), "session-timeout-worker", 
log) {
@@ -479,9 +477,8 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
                             Session ses = e.getValue();
 
                             if (ses.isTimedOut(sesTtl)) {
-                                sesId2Ses.remove(ses.sesId, ses);
-
                                 clientId2SesId.remove(ses.clientId, ses.sesId);
+                                sesId2Ses.remove(ses.sesId, ses);
                             }
                         }
                     }
@@ -607,7 +604,7 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
             return;
 
         if (req instanceof GridRestCacheRequest) {
-            GridRestCacheRequest req0 = (GridRestCacheRequest) req;
+            GridRestCacheRequest req0 = (GridRestCacheRequest)req;
 
             req0.key(interceptor.onReceive(req0.key()));
             req0.value(interceptor.onReceive(req0.value()));
@@ -625,7 +622,7 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
             }
         }
         else if (req instanceof GridRestTaskRequest) {
-            GridRestTaskRequest req0 = (GridRestTaskRequest) req;
+            GridRestTaskRequest req0 = (GridRestTaskRequest)req;
 
             List<Object> oldParams = req0.params();
 
@@ -731,7 +728,7 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
         Object creds = req.credentials();
 
         if (creds instanceof SecurityCredentials)
-            return  (SecurityCredentials)creds;
+            return (SecurityCredentials)creds;
 
         if (creds instanceof String) {
             String credStr = (String)creds;
@@ -757,7 +754,7 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
      * @return Authentication subject context.
      * @throws IgniteCheckedException If authentication failed.
      */
-    private SecurityContext authenticate(GridRestRequest req) throws 
IgniteCheckedException {
+    private SecurityContext authenticate(GridRestRequest req, Session ses) 
throws IgniteCheckedException {
         assert req.clientId() != null;
 
         AuthenticationContext authCtx = new AuthenticationContext();
@@ -766,10 +763,24 @@ public class GridRestProcessor extends 
GridProcessorAdapter {
         authCtx.subjectId(req.clientId());
         authCtx.nodeAttributes(Collections.<String, Object>emptyMap());
         authCtx.address(req.address());
-        authCtx.credentials(credentials(req));
+
+        SecurityCredentials creds = credentials(req);
+
+        if (creds.getLogin() == null) {
+            SecurityCredentials sesCreds = ses.creds;
+
+            if (sesCreds != null)
+                creds = ses.creds;
+        }
+        else
+            ses.creds = creds;
+
+        authCtx.credentials(creds);
 
         SecurityContext subjCtx = ctx.security().authenticate(authCtx);
 
+        ses.lastInvalidateTime.set(U.currentTimeMillis());
+
         if (subjCtx == null) {
             if (req.credentials() == null)
                 throw new IgniteCheckedException("Failed to authenticate 
remote client (secure session SPI not set?): " + req);
@@ -839,7 +850,13 @@ public class GridRestProcessor extends 
GridProcessorAdapter {
             case EXE:
             case RESULT:
                 perm = SecurityPermission.TASK_EXECUTE;
-                name = ((GridRestTaskRequest)req).taskName();
+
+                GridRestTaskRequest taskReq = (GridRestTaskRequest)req;
+                name = taskReq.taskName();
+
+                // We should extract task name wrapped by VisorGatewayTask.
+                if (VisorGatewayTask.class.getName().equals(name))
+                    name = (String)taskReq.params().get(WRAPPED_TASK_IDX);
 
                 break;
 
@@ -880,7 +897,6 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
     }
 
     /**
-     *
      * @return Whether or not REST is enabled.
      */
     private boolean isRestEnabled() {
@@ -972,7 +988,7 @@ public class GridRestProcessor extends GridProcessorAdapter 
{
      * Session.
      */
     private static class Session {
-        /** Expiration flag. It's a final state of lastToucnTime. */
+        /** Expiration flag. It's a final state of lastTouchTime. */
         private static final Long TIMEDOUT_FLAG = 0L;
 
         /** Client id. */
@@ -987,12 +1003,18 @@ public class GridRestProcessor extends 
GridProcessorAdapter {
          */
         private final AtomicLong lastTouchTime = new 
AtomicLong(U.currentTimeMillis());
 
+        /** Time when session token was invalidated last time. */
+        private final AtomicLong lastInvalidateTime = new 
AtomicLong(U.currentTimeMillis());
+
         /** Security context. */
         private volatile SecurityContext secCtx;
 
         /** Authorization context. */
         private volatile AuthorizationContext authCtx;
 
+        /** Credentials that can be used for security token invalidation.*/
+        private volatile SecurityCredentials creds;
+
         /**
          * @param clientId Client ID.
          * @param sesId session ID.
@@ -1048,6 +1070,16 @@ public class GridRestProcessor extends 
GridProcessorAdapter {
         }
 
         /**
+         * Checks if session token should be invalidated.
+         *
+         * @param sesTokTtl Session token expire time.
+         * @return {@code true} if session token should be invalidated.
+         */
+        boolean isTokenExpired(long sesTokTtl) {
+            return U.currentTimeMillis() - lastInvalidateTime.get() > 
sesTokTtl;
+        }
+
+        /**
          * Checks whether session at expired state (EXPIRATION_FLAG) or not, 
if not then tries to update last touch time.
          *
          * @return {@code False} if session timed out (not successfully 
touched).

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
index ee0a54b..e213bf4 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
@@ -185,8 +185,9 @@ public class VisorGatewayTask implements 
ComputeTask<Object[], Object> {
 
                 Class<?> valCls = Class.forName(valClsName);
 
-                return new IgniteBiTuple<>(toObject(keyCls, 
(String)argument(startIdx + 2)),
-                    toObject(valCls, (String)argument(startIdx + 3)));
+                return new IgniteBiTuple<>(
+                    toObject(keyCls, argument(startIdx + 2)),
+                    toObject(valCls, argument(startIdx + 3)));
             }
 
             if (cls == Map.class) {
@@ -229,8 +230,10 @@ public class VisorGatewayTask implements 
ComputeTask<Object[], Object> {
                 Class<?> v2Cls = Class.forName(v2ClsName);
                 Class<?> v3Cls = Class.forName(v3ClsName);
 
-                return new GridTuple3<>(toObject(v1Cls, 
(String)argument(startIdx + 3)), toObject(v2Cls,
-                    (String)argument(startIdx + 4)), toObject(v3Cls, 
(String)argument(startIdx + 5)));
+                return new GridTuple3<>(
+                    toObject(v1Cls, argument(startIdx + 3)),
+                    toObject(v2Cls, argument(startIdx + 4)),
+                    toObject(v3Cls, argument(startIdx + 5)));
             }
 
             return toObject(cls, arg);

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8be8c2b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
 
b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
index 370eadd..fa7c748 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityBasicPermissionSet.java
@@ -36,8 +36,8 @@ import static 
org.apache.ignite.internal.processors.security.SecurityUtils.isSec
 import static 
org.apache.ignite.internal.processors.security.SecurityUtils.serializeVersion;
 
 /**
- * Simple implementation of {@link SecurityPermissionSet} interface. Provides
- * convenient way to specify permission set in the XML configuration.
+ * Simple implementation of {@link SecurityPermissionSet} interface.
+ * Provides convenient way to specify permission set in the XML configuration.
  */
 public class SecurityBasicPermissionSet implements SecurityPermissionSet {
     /** Serial version uid. */

Reply via email to