Apache Ignite节点认证实现

为了保证缓存中数据的安全性,私密性。我们的需求是打开Ignite的安全认证机制,不允许非法的Ignite节点或者JDBC连接能够连上我们的生产Ignite集群;必须持有有效的身份信息(用户名、密码)才能够连上现有集群。

为了实现这一需求,我首先从Ignite文档入手,文档推荐修改配置,添加插件,实现接口。。我跟着一步步实现了,但是到最后需要在Ignite启动时声明SecurityCredentials(用户名,密码)的时候,所有文档和社区中完全找不到一种有效方式能够实现,我自己调查了半天也没有思路。于是我转向stackoverflow,终于在一个post中找到了一种解决方案,这个方案跟文档指定的思路完全不同。。并且比文档的实现思路要简单很多很多。。。

所以直接把这个链接发出来,如果有人需要实现Ignite认证的话可以直接参照这个post来:
https://stackoverflow.com/questions/51261521/authentication-for-apache-ignite-2-5


下面是文档的解决思路,目前不知道怎么走通这条线。但还是记录一下过程,未来也许会解决。

IgniteConfiguration中把这个开关打开:

其实只是管控住了JDBC连接,比如我通过DBeaver这种工具,连接localhost:10800时,会强制我输入用户名密码。这里如果用IgniteThinClient的话应该也会受限制,我还没有试,因为它也是通过JDBC创建连接。

但是,别的Ignite Server/Client节点加入进来还是不受管控。如果想要在这一层也做安全管控的话,还是要通过实现Ignite的GridSecurityProcessor接口来做一个插件来完成。

接下来会不断尝试如何实现这一步。我用的是Ignite当前最新版本2.7


首先基本大家都能找到这篇文章:http://smartkey.co.uk/development/securing-an-apache-ignite-cluster/
这篇写得比较早,当时还是Ignite 1.5版本,现在升级后不能完全适用,但是能给大家带来一个好的开始。

然后我按照这篇文章指导之后,发现无法加载到自定义的插件。
最后查阅社区,发现是Ignite文档中放置路径没写对。文件应该这样放:
在这里插入图片描述
放对位置之后,发现能够加载到插件了。此时在Ignite启动日志中会打印出来:
在这里插入图片描述
这里打印出来的是name, version, copyright,你都可以随便写。

以下是根据上面文章中生成的代码:

import org.apache.ignite.plugin.PluginConfiguration;
import org.apache.ignite.plugin.PluginProvider;

public class WhiteListPluginConfiguration implements PluginConfiguration {
  
  public Class providerClass() {
    return WhiteListPluginProvider.class;
  }
  
}
import java.io.Serializable;
import java.util.UUID;

import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.processors.security.GridSecurityProcessor;
import org.apache.ignite.plugin.CachePluginContext;
import org.apache.ignite.plugin.CachePluginProvider;
import org.apache.ignite.plugin.ExtensionRegistry;
import org.apache.ignite.plugin.IgnitePlugin;
import org.apache.ignite.plugin.PluginContext;
import org.apache.ignite.plugin.PluginProvider;
import org.apache.ignite.plugin.PluginValidationException;

public class WhiteListPluginProvider implements PluginProvider {

  @Override
  public String name() {
    return "WhiteListSecurityProcessor";
  }

  @Override
  public String version() {
    return "0.0.1";
  }

  @Override
  public String copyright() {
    return "Pilot FAST team - Jeff Jiao";
  }

  @SuppressWarnings("unchecked")
  @Override
  public  T plugin() {
    return (T) new WhiteListSecurityProcessor();
  }

  @Override
  public void initExtensions(PluginContext ctx, ExtensionRegistry registry) throws IgniteCheckedException {
    // TODO Auto-generated method stub

  }

  @Override
  public  T createComponent(PluginContext ctx, Class cls) {
    if (cls.isAssignableFrom(GridSecurityProcessor.class)) {
      return (T) new WhiteListSecurityProcessor();
    } else {
      return null;
    }
  }

  @Override
  public CachePluginProvider createCacheProvider(CachePluginContext ctx) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void start(PluginContext ctx) throws IgniteCheckedException {
    // TODO Auto-generated method stub

  }

  @Override
  public void stop(boolean cancel) throws IgniteCheckedException {
    // TODO Auto-generated method stub

  }

  @Override
  public void onIgniteStart() throws IgniteCheckedException {
    // TODO Auto-generated method stub

  }

  @Override
  public void onIgniteStop(boolean cancel) {
    // TODO Auto-generated method stub

  }

  @Override
  public Serializable provideDiscoveryData(UUID nodeId) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void receiveDiscoveryData(UUID nodeId, Serializable data) {
    // TODO Auto-generated method stub

  }

  @Override
  public void validateNewNode(ClusterNode node) throws PluginValidationException {
    // TODO Auto-generated method stub

  }

}
import java.util.Collection;
import java.util.UUID;

import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.security.GridSecurityProcessor;
import org.apache.ignite.internal.processors.security.SecurityContext;
import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.plugin.IgnitePlugin;
import org.apache.ignite.plugin.security.AuthenticationContext;
import org.apache.ignite.plugin.security.SecurityCredentials;
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.spi.IgniteNodeValidationResult;
import org.apache.ignite.spi.discovery.DiscoveryDataBag;
import org.apache.ignite.spi.discovery.DiscoveryDataBag.GridDiscoveryData;
import org.apache.ignite.spi.discovery.DiscoveryDataBag.JoiningNodeDiscoveryData;

public class WhiteListSecurityProcessor implements IgnitePlugin, GridSecurityProcessor {

  @Override
  public void start() throws IgniteCheckedException {
    // TODO Auto-generated method stub

  }

  @Override
  public void stop(boolean cancel) throws IgniteCheckedException {
    // TODO Auto-generated method stub

  }

  @Override
  public void onKernalStart(boolean active) throws IgniteCheckedException {
    // TODO Auto-generated method stub

  }

  @Override
  public void onKernalStop(boolean cancel) {
    // TODO Auto-generated method stub

  }

  @Override
  public void collectJoiningNodeData(DiscoveryDataBag dataBag) {
    // TODO Auto-generated method stub

  }

  @Override
  public void collectGridNodeData(DiscoveryDataBag dataBag) {
    // TODO Auto-generated method stub

  }

  @Override
  public void onGridDataReceived(GridDiscoveryData data) {
    // TODO Auto-generated method stub

  }

  @Override
  public void onJoiningNodeDataReceived(JoiningNodeDiscoveryData data) {
    // TODO Auto-generated method stub

  }

  @Override
  public void printMemoryStats() {
    // TODO Auto-generated method stub

  }

  @Override
  public IgniteNodeValidationResult validateNode(ClusterNode node) {
    if (!node.attribute("assertion").equals("IgniteClient")) {
      return new IgniteNodeValidationResult(node.id(), "Access denied", "Access denied");
    } else {
      return null;
    }
  }

  @Override
  public IgniteNodeValidationResult validateNode(ClusterNode node, JoiningNodeDiscoveryData discoData) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public DiscoveryDataExchangeType discoveryDataType() {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void onDisconnected(IgniteFuture reconnectFut) throws IgniteCheckedException {
    // TODO Auto-generated method stub

  }

  @Override
  public IgniteInternalFuture onReconnected(boolean clusterRestarted) throws IgniteCheckedException {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public SecurityContext authenticateNode(ClusterNode node, SecurityCredentials cred) throws IgniteCheckedException {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public boolean isGlobalNodeAuthentication() {
    return false;
  }

  @Override
  public SecurityContext authenticate(AuthenticationContext ctx) throws IgniteCheckedException {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public Collection authenticatedSubjects() throws IgniteCheckedException {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public SecuritySubject authenticatedSubject(UUID subjId) throws IgniteCheckedException {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void authorize(String name, SecurityPermission perm, SecurityContext securityCtx) throws SecurityException {
    // TODO Auto-generated method stub

  }

  @Override
  public void onSessionExpired(UUID subjId) {
    // TODO Auto-generated method stub

  }

  @Override
  public boolean enabled() {
    return true;
  }

}

最后跑起来时候,进入authenticateNode方法时,传入的credential参数一直为null,无法插入,卡在了这里。
无法通过userAttribute插入,因为credential的默认key值被Ignite预留了,不让用户使用。

你可能感兴趣的:(Apache Ignite节点认证实现)