问题
I just configured authentication in IgniteDB ( a specific server, not a localhost ) https://apacheignite.readme.io/docs/advanced-security
However I encountered some issue while trying to connect. Where should I provide the credential?
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
String ipList = appConfig.getIgniteIPAddressList();
List<String> addressList= Arrays.asList(ipList.split(";"));
ipFinder.setAddresses(addressList);
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setIgniteInstanceName("IgnitePod");
cfg.setClientMode(true);
cfg.setDiscoverySpi(spi);
Ignite ignite = Ignition.start(cfg);
Anybody has idea on implementing it?
回答1:
https://apacheignite.readme.io/docs/advanced-security
Describes how to configure the authentication via username and password for THIN connections only (JDBC, ODBC).
You can create users using SQL commands like next:
https://apacheignite-sql.readme.io/docs/create-user
You can provide credentials to thin client connection string using its properties:
https://apacheignite-sql.readme.io/docs/connection-string-and-dsn#section-supported-arguments https://apacheignite-sql.readme.io/docs/jdbc-driver#section-additional-connection-string-examples
Please also check that you have Ignite persistence configured.
回答2:
As Andrei notes, Ignite only authenticates thin clients by default, and even then only when persistence is enabled. If you need to have thick-clients authenticate also, you can do this using a plugin. Third-party, commercial solutions also exist.
回答3:
The only option for peer-authenticating server nodes which is available in vanilla Apache Ignite is SSL+certificates.
回答4:
Was able to solve my own problem by creating my own CustomTCPDiscoveryAPI. First, create this class :
import org.apache.ignite.IgniteException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.IgniteNodeAttributes;
import org.apache.ignite.internal.processors.security.SecurityContext;
import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.plugin.security.SecurityCredentials;
import org.apache.ignite.spi.discovery.DiscoverySpiNodeAuthenticator;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import java.util.Map;
public class CustomTcpDiscoverySpi extends TcpDiscoverySpi implements DiscoverySpiNodeAuthenticator {
SecurityCredentials securityCredentials;
public CustomTcpDiscoverySpi(final SecurityCredentials securityCredentials) {
this.securityCredentials = securityCredentials;
this.setAuthenticator(this);
}
@Override
public SecurityContext authenticateNode(ClusterNode clusterNode, SecurityCredentials securityCredentials) throws IgniteException {
return null;
}
@Override
public boolean isGlobalNodeAuthentication() {
return true;
}
@Override
public void setNodeAttributes(final Map<String, Object> attrs, final IgniteProductVersion ver) {
attrs.put(IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS, this.securityCredentials);
super.setNodeAttributes(attrs, ver);
}
}
And then, use it like below :
SecurityCredentials cred = new SecurityCredentials();
cred.setLogin(appConfig.getIgniteUser());
cred.setPassword(appConfig.getIgnitePassword());
CustomTcpDiscoverySpi spi = new CustomTcpDiscoverySpi(cred);
//TcpDiscoverySpi spi = new TcpDiscoverySpi(); - > removed to use the CustomTCPDiscovery
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
String ipList = appConfig.getIgniteIPAddressList();
List<String> addressList= Arrays.asList(ipList.split(";"));
ipFinder.setAddresses(addressList);
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setIgniteInstanceName("IgnitePod");
cfg.setClientMode(true);
cfg.setAuthenticationEnabled(true);
// Ignite persistence configuration.
DataStorageConfiguration storageCfg = new DataStorageConfiguration();
// Enabling the persistence.
storageCfg.getDefaultDataRegionConfiguration().setPersistenceEnabled(true);
// Applying settings.
// tests
cfg.setDataStorageConfiguration(storageCfg);
cfg.setDiscoverySpi(spi);
Ignite ignite = Ignition.start(cfg);
Hope this helps other people who stuck with the same problem.
回答5:
Apache Ignite does not provide these kinds of security capabilities with its open-source version. One can either implement it on your own or use commercial Gridgain distribution.
Here are the steps to implement a custom security plugin.
One would need to implement GridSecurityProcessor
which would be used to authenticate the joining node.
In GridSecurityProcessor
, you would have to implement authenticateNode()
api as follows
public SecurityContext authenticateNode(ClusterNode node, SecurityCredentials cred) throws IgniteCheckedException {
SecurityCredentials userSecurityCredentials;
if (securityPluginConfiguration != null) {
if ((userSecurityCredentials = securityPluginConfiguration.getSecurityCredentials()) != null) {
return userSecurityCredentials.equals(cred) ? new SecurityContextImpl() : null;
}
if (cred == null && userSecurityCredentials == null) {
return new SecurityContextImpl();
}
}
if (cred == null)
return new SecurityContextImpl();
return null;
}
Also, you would need to extend TcpDiscoverySpi
to pass the user credentials during initLocalNode()
as follows
@Override
protected void initLocalNode(int srvPort, boolean addExtAddrAttr) {
try {
super.initLocalNode(srvPort, addExtAddrAttr);
this.setSecurityCredentials();
} catch (Exception e) {
e.printStackTrace();
}
}
private void setSecurityCredentials() {
if (securityCredentials != null) {
Map<String,Object> attributes = new HashMap<>(locNode.getAttributes());
attributes.put(IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS, securityCredentials);
this.locNode.setAttributes(attributes);
}
}
You can follow the link given below to get detailed steps that can be followed to write a custom security plugin and its usage.
https://www.bugdbug.com/post/how-to-secure-apache-ignite-cluster
来源:https://stackoverflow.com/questions/59610118/implementing-authentication-in-ignitedb