diff --git a/src/Datasource/DatasourceInterface.php b/src/Datasource/DatasourceInterface.php
index 1fdc5df..857d2f2 100644
--- a/src/Datasource/DatasourceInterface.php
+++ b/src/Datasource/DatasourceInterface.php
@@ -132,4 +132,13 @@ interface DatasourceInterface extends IndexPluginInterface {
    */
   public function viewMultipleItems(array $items, $view_mode, $langcode = NULL);
 
+  /**
+   * Gets the entity type id.
+   *
+   * @return string|null
+   *   Entity type id if the data source contains entities.
+   *
+   */
+  public function getEntityTypeId();
+
 }
diff --git a/src/Plugin/SearchApi/Datasource/ContentEntityDatasource.php b/src/Plugin/SearchApi/Datasource/ContentEntityDatasource.php
index 24c34b9..812a427 100644
--- a/src/Plugin/SearchApi/Datasource/ContentEntityDatasource.php
+++ b/src/Plugin/SearchApi/Datasource/ContentEntityDatasource.php
@@ -338,6 +338,13 @@ class ContentEntityDatasource extends DatasourcePluginBase implements ContainerF
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function getDatasourceType() {
+    return $this->getEntityType()->id();
+  }
+
+  /**
    * Determine whether the entity type supports bundles.
    *
    * @return bool
diff --git a/src/Plugin/SearchApi/Processor/CommentAccess.php b/src/Plugin/SearchApi/Processor/CommentAccess.php
index fe414e7..fec9468 100644
--- a/src/Plugin/SearchApi/Processor/CommentAccess.php
+++ b/src/Plugin/SearchApi/Processor/CommentAccess.php
@@ -15,13 +15,18 @@ use Drupal\search_api\Index\IndexInterface;
 class CommentAccess extends NodeAccess {
 
   /**
+   * Defines the entity type id that this processor can handle.
+   *
+   * @var string
+   */
+  protected static $entityTypeId = 'comment';
+
+  /**
    * {@inheritdoc}
    */
   public static function supportsIndex(IndexInterface $index) {
-    // @todo Re-introduce Datasource::getEntityType() for this?
     foreach ($index->getDatasources() as $datasource) {
-      $definition = $datasource->getPluginDefinition();
-      if (isset($definition['entity_type']) && $definition['entity_type'] === 'comment') {
+      if ($datasource->getEntityTypeId() == self::$entityTypeId) {
         return TRUE;
       }
     }
diff --git a/src/Plugin/SearchApi/Processor/NodeAccess.php b/src/Plugin/SearchApi/Processor/NodeAccess.php
index 5220125..a8dab0d 100644
--- a/src/Plugin/SearchApi/Processor/NodeAccess.php
+++ b/src/Plugin/SearchApi/Processor/NodeAccess.php
@@ -6,8 +6,10 @@
 
 namespace Drupal\search_api\Plugin\SearchApi\Processor;
 
+use Drupal\Core\Session\AnonymousUserSession;
 use Drupal\Core\TypedData\DataDefinition;
 use Drupal\search_api\Datasource\DatasourceInterface;
+use Drupal\search_api\Exception\SearchApiException;
 use Drupal\search_api\Index\IndexInterface;
 use Drupal\search_api\Processor\ProcessorPluginBase;
 use Drupal\search_api\Query\QueryInterface;
@@ -22,13 +24,18 @@ use Drupal\search_api\Query\QueryInterface;
 class NodeAccess extends ProcessorPluginBase {
 
   /**
+   * Defines the entity type id that this processor can handle.
+   *
+   * @var string
+   */
+  protected static $entityTypeId = 'node';
+
+  /**
    * {@inheritdoc}
    */
   public static function supportsIndex(IndexInterface $index) {
-    // @todo Re-introduce Datasource::getEntityType() for this?
     foreach ($index->getDatasources() as $datasource) {
-      $definition = $datasource->getPluginDefinition();
-      if (isset($definition['entity_type']) && $definition['entity_type'] === 'node') {
+      if ($datasource->getEntityTypeId() == self::$entityTypeId) {
         return TRUE;
       }
     }
@@ -61,27 +68,31 @@ class NodeAccess extends ProcessorPluginBase {
 
     if (!isset($account)) {
       // Load the anonymous user.
-      $account = drupal_anonymous_user();
+      $account = new AnonymousUserSession();
     }
 
     foreach ($items as $id => $item) {
-      // @todo Only process nodes (check '#datasource' key).
+      if (!in_array($this->index->getDatasource($item['#datasource'])->getEntityTypeId(), array('node', 'comment'))) {
+        continue;
+      }
+
       /** @var $node \Drupal\Node\NodeInterface */
-      $node = $this->getNode($item);
-      // Check whether all users have access to the node.
+      $node = $this->getNode($item['#item']);
+      // If the view access is not granted by default to anonymous user check
+      // for grants.
       if (!$node->access('view', $account)) {
         // Get node access grants.
         $result = db_query('SELECT * FROM {node_access} WHERE (nid = 0 OR nid = :nid) AND grant_view = 1', array(':nid' => $node->id()));
 
         // Store all grants together with their realms in the item.
         foreach ($result as $grant) {
-          $items[$id]->search_api_access_node[] = "node_access_{$grant->realm}:{$grant->gid}";
+          $items[$id]['search_api_access_node'][] = "node_access_{$grant->realm}:{$grant->gid}";
         }
       }
       else {
         // Add the generic view grant if we are not using node access or the
         // node is viewable by anonymous users.
-        $items[$id]->search_api_access_node = array('node_access__all');
+        $items[$id]['search_api_access_node'] = array('node_access__all');
       }
     }
   }
@@ -130,7 +141,26 @@ class NodeAccess extends ProcessorPluginBase {
    * {@inheritdoc}
    */
   public function preprocessSearchQuery(QueryInterface $query) {
-    // @todo Implement.
+    $entity_type_id = $this->index->getDatasource(self::$entityTypeId)->getEntityTypeId();
+    $options = $this->index->getOptions();
+
+    if (!empty($options['data_alter_callbacks']["search_api_alter_{$entity_type_id}_access"]['status']) && !$query->getOption('search_api_bypass_access')) {
+      $account = $query->getOption('search_api_access_account', \Drupal::currentUser());
+      if (is_numeric($account)) {
+        $account = user_load($account);
+      }
+      if (is_object($account)) {
+        try {
+          _search_api_query_add_node_access($account, $query, $entity_type_id);
+        }
+        catch (SearchApiException $e) {
+          watchdog_exception('search_api', $e);
+        }
+      }
+      else {
+        watchdog('search_api', 'An illegal user UID was given for node access: @uid.', array('@uid' => $query->getOption('search_api_access_account', \Drupal::currentUser())), WATCHDOG_WARNING);
+      }
+    }
   }
 
 }
diff --git a/src/Tests/SearchApiCommentAccessProcessorTest.php b/src/Tests/SearchApiCommentAccessProcessorTest.php
new file mode 100644
index 0000000..974ec59
--- /dev/null
+++ b/src/Tests/SearchApiCommentAccessProcessorTest.php
@@ -0,0 +1,186 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\search_api\Tests\SearchApiCommentAccessProcessorTest.
+ */
+
+namespace Drupal\search_api\Tests;
+
+use Drupal\search_api\Plugin\SearchApi\Processor\CommentAccess;
+use Drupal\system\Tests\Entity\EntityUnitTestBase;
+
+/**
+ * Tests the CommentAccess processor.
+ */
+class SearchApiCommentAccessProcessorTest extends EntityUnitTestBase {
+
+  /**
+   * Modules to enable for this test.
+   *
+   * @var array
+   */
+  public static $modules = array('user', 'node', 'search_api', 'comment', 'entity_reference');
+
+  /**
+   * The processor used for these tests.
+   *
+   * @var \Drupal\search_api\Processor\ProcessorInterface
+   */
+  protected $processor;
+
+  /**
+   * @var \Drupal\comment\Entity\Comment[]
+   */
+  protected $comments;
+
+  /**
+   * @var \Drupal\node\Entity\Node
+   */
+  protected $node;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Tests CommentAccess Processor Plugin',
+      'description' => 'Tests if node access processor lets through only nodes',
+      'group' => 'Search API',
+    );
+  }
+
+  /**
+   * Creates a new processor object for use in the tests.
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $name = $this->randomName();
+    $index = entity_create('search_api_index', array(
+      'machine_name' => strtolower($name),
+      'name' => $name,
+      'status' => TRUE,
+      'datasourcePluginIds' => array('entity:comment')
+    ));
+    $index->save();
+
+    /** @var \Drupal\search_api\Processor\ProcessorPluginManager $plugin_manager */
+    $plugin_manager = \Drupal::service('plugin.manager.search_api.processor');
+    $this->processor = $plugin_manager->createInstance('search_api_node_access_processor', array('index' => $index));
+
+    $this->installSchema('node', array('node', 'node_field_data', 'node_field_revision', 'node_revision', 'node_access'));
+    $this->installSchema('comment', array('comment'));
+
+    // Create a node type for testing.
+    $type = entity_create('node_type', array('type' => 'page', 'name' => 'page'));
+    $type->save();
+
+    // Create anonymous user name.
+    $role = entity_create('user_role', array(
+      'id' => 'anonymous',
+      'label' => 'anonymous',
+    ));
+    $role->save();
+
+    // Create a node with attached comment.
+    $this->node = entity_create('node', array('status' => NODE_PUBLISHED, 'type' => 'page'));
+    $this->node->save();
+    entity_reference_create_instance('node', 'page', 'comments', 'Comments', 'comment');
+    $comment = entity_create('comment', array('entity_type' => 'node', 'entity_id' => $this->node->id(), 'field_id' => 'node__comments'));
+    $comment->save();
+
+    $this->comments[] = $comment;
+  }
+
+  /**
+   *  Test scenario all users have access to content.
+   */
+  public function testCommentAccessAll() {
+    user_role_grant_permissions('anonymous', array('access content', 'access comments'));
+
+    $items = array();
+    foreach ($this->comments as $comment) {
+      $items[] = array(
+        'datasource' => 'entity:comment',
+        'item' => $comment,
+        'item_id' => $comment->id(),
+        'text' => $this->randomName(),
+      );
+    }
+    $items = $this->generateItems($items);
+
+    $this->processor->preprocessIndexItems($items);
+    foreach ($items as $item) {
+      $this->assertEqual($item['search_api_access_node'], array('node_access__all'));
+    }
+  }
+
+  /**
+   * Tests scenario where hook_node_grants() take effect.
+   */
+  public function testCommentAccessWithNodeGrants() {
+    db_insert('node_access')
+      ->fields(array(
+        'nid' => $this->node->id(),
+        'langcode' => $this->node->language()->id,
+        'gid' => 1,
+        'realm' => 'test_realm',
+        'grant_view' => 1,
+      ))
+      ->execute();
+
+    $items = array();
+    foreach ($this->comments as $comment) {
+      $items[] = array(
+        'datasource' => 'entity:comment',
+        'item' => $comment,
+        'item_id' => $comment->id(),
+        'text' => $this->randomName(),
+      );
+    }
+    $items = $this->generateItems($items);
+
+    $this->processor->preprocessIndexItems($items);
+    foreach ($items as $item) {
+      $this->assertEqual($item['search_api_access_node'], array('node_access_test_realm:1'));
+    }
+  }
+
+  /**
+   * Populates testing items.
+   *
+   * @param array $items
+   *   Data to populate test items.
+   *    - datasource: The datasource plugin id.
+   *    - item: The item object to be indexed.
+   *    - item_id: Unique item id.
+   *    - text: Textual value of the test field.
+   *
+   * @return array
+   *   The items structure.
+   */
+  public function generateItems (array $items) {
+    $extracted_items = array();
+    foreach ($items as $item) {
+      $extracted_items[$item['datasource'] . '|' . $item['item_id']] = array(
+        '#item' => $item['item'],
+        '#datasource' => $item['datasource'],
+        '#item_id' => $item['item_id'],
+        'id' => array(
+          'type' => 'integer',
+          'original_type' => 'field_item:integer',
+          'value' => array($item['item_id']),
+        ),
+        'field_text' => array(
+          'type' => 'text',
+          'original_type' => 'field_item:string',
+          'value' => array($item['text']),
+        ),
+      );
+    }
+
+    return $extracted_items;
+  }
+
+}
