公司的一个项目TEST环境ES不需要授权、UAT环境使用x-pack做鉴权;这我看着官方文档写的代码不兼容了呀,也就出现了授权失败的问题;再加上我也是第一次遇到ES做鉴权的场景,以前公司直接就可以访问。
环境信息如下:
ElasticSearch版本:5.6.16x-pack版本:5.6.16
主要异常信息org.elasticsearch.transport.RemoteTransportException: [Z2KL4U0][100.10.10.100:9300][cluster:monitor/nodes/liveness] Caused by: org.elasticsearch.ElasticsearchSecurityException: missing authentication token for action [cluster:monitor/nodes/liveness]整个异常复现过程 1、参照官网使用TransportClient连接ES
官网地址:https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.6/transport-client.html。
使用TransportClient连接ES的代码如下:
1)ElasticSearchConfig类:
@Configuration @Slf4j public class ElasticSearchConfig { @Value("${elasticsearch.hostList}") private String hostList; @Value("${elasticsearch.clusterName}") private String clusterName; @Bean public TransportClient transportClient() { log.info("es hostList: {}, clusterName: {}", hostList, clusterName); String[] hostArray = hostList.split(",|;"); int hostCount = hostArray.length; Settings settings = Settings.builder().put("cluster.name", clusterName).build(); TransportClient transportClient = new PreBuiltTransportClient(settings); for (int i = 0; i < hostCount; i++) { String addr = hostArray[i]; if (addr == null || addr.equals("")) { continue; } try { TransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(addr.split(":")[0]), Integer.parseInt(addr.split(":")[1])); transportClient.addTransportAddresses(transportAddress); } catch (UnknownHostException e) { log.error("Fail to init es client", e); } } log.info("success to init elasticsearch transport client"); return transportClient; } }
2)application.yml:
elasticsearch: hostList: 127.0.0.1:9300 indexName: idx_inventory_inventoryline clusterName: es-sg
run application,报错:
Caused by: org.elasticsearch.ElasticsearchSecurityException: missing authentication token for action [cluster:monitor/nodes/liveness]
报错很明确:没权限,这时候我们很自然的想到在Setting中加入用户名和密码,然而TransportClient它没有这个能力;这时x-pack-transport也就要登场了。
2、使用x-pack-transport解决授权问题官方文档:https://www.elastic.co/guide/en/x-pack/5.6/index.html
1> 引入x-pack-transport maven依赖官方文档:https://www.elastic.co/guide/en/x-pack/5.6/api-java.html#_installing_xpackclient;
... ... elasticsearch-releases https://artifacts.elastic.co/maven true false ... ... org.elasticsearch.client x-pack-transport5.6.16
在maven repository中我们可以看到x-pack-transport的最老版本是6.8.11,而它和ES5.x版本是不兼容的,所以我们需要在pom中引入url为https://artifacts.elastic.co/maven的repository信息;
不过有时我们从https://artifacts.elastic.co/maven也拉不到x-pack-transport的5.X版本(或者说直接就从私服上拉不到),比如我这样的:
好巧不巧的看到maven repository的Spring Pluginstab中有5.6.X版本的;
于是直接拿来用了,发现可以正常引入/使用;
2> 使用PreBuiltXPackTransportClientorg.elasticsearch.client x-pack-transport5.6.1
官方文档:https://www.elastic.co/guide/en/x-pack/current/java-clients.html#java-clients;
在自动注入TransportClient的地方 使用PreBuiltXPackTransportClient替代PreBuiltTransportClient;
application.yml
elasticsearch: hostList: 127.0.0.1:9300 indexName: idx_inventory_inventoryline clusterName: es-sg userName: elastic password: elastic security: enable: true
ElasticSearchConfig类:
@Configuration @Slf4j public class ElasticSearchConfig { @Value("${elasticsearch.hostList}") private String hostList; @Value("${elasticsearch.clusterName}") private String clusterName; @Value("${elasticsearch.password}") private String password; @Value("${elasticsearch.userName}") private String userName; @Bean public TransportClient transportClient() { log.info("es hostList: {}, clusterName: {}", hostList, clusterName); String[] hostArray = hostList.split(",|;"); int hostCount = hostArray.length; Settings settings = Settings.builder() .put("cluster.name", clusterName) // 设置xpack权限用户 .put("xpack.security.user", userName + ":" + password) .build(); TransportClient transportClient = new PreBuiltXPackTransportClient(settings); for (int i = 0; i < hostCount; i++) { String addr = hostArray[i]; if (addr == null || addr.equals("")) { continue; } try { TransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(addr.split(":")[0]), Integer.parseInt(addr.split(":")[1])); transportClient.addTransportAddresses(transportAddress); } catch (UnknownHostException e) { log.error("Fail to init es client", e); } } log.info("success to init elasticsearch transport client"); return transportClient; } }2> 使用x-pack和不使用时做兼容处理
由于我们测试环境和UAT环境一个ES要授权、一个不需要,所以要在一套代码中做兼容处理(搞个开关,判断一下);也就是测试环境使用PreBuiltTransportClient,UAT环境使用PreBuiltXPackTransportClient。
代码如下:
@Configuration @Slf4j public class ElasticSearchConfig { @Value("${elasticsearch.hostList}") private String hostList; @Value("${elasticsearch.clusterName}") private String clusterName; @Value("${elasticsearch.password}") private String password; @Value("${elasticsearch.userName}") private String userName; @Value("${elasticsearch.security.enable}") private Boolean enableSecurity = false; // @PostConstruct // void init() { // System.setProperty("es.set.netty.runtime.available.processors", "false"); // } @Bean public TransportClient transportClient() { log.info("es hostList: {}, clusterName: {}", hostList, clusterName); String[] hostArray = hostList.split(",|;"); int hostCount = hostArray.length; Settings settings; TransportClient transportClient; if (enableSecurity) { settings = Settings.builder() .put("cluster.name", clusterName) // 设置xpack权限用户 .put("xpack.security.user", userName + ":" + password) // .put("client.transport.sniff", true) .build(); transportClient = new PreBuiltXPackTransportClient(settings); } else { settings = Settings.builder().put("cluster.name", clusterName).build(); transportClient = new PreBuiltTransportClient(settings); } for (int i = 0; i < hostCount; i++) { String addr = hostArray[i]; if (addr == null || addr.equals("")) { continue; } try { TransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(addr.split(":")[0]), Integer.parseInt(addr.split(":")[1])); transportClient.addTransportAddresses(transportAddress); } catch (UnknownHostException e) { log.error("Fail to init es client", e); } } log.info("success to init elasticsearch transport client"); return transportClient; } }
run application,已经可以正常运行了;
具体异常信息org.elasticsearch.transport.RemoteTransportException: [Z2KL4U0][100.10.10.100:9300][cluster:monitor/nodes/liveness] Caused by: org.elasticsearch.ElasticsearchSecurityException: missing authentication token for action [cluster:monitor/nodes/liveness] at org.elasticsearch.xpack.security.support.Exceptions.authenticationError(Exceptions.java:39) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.DefaultAuthenticationFailureHandler.missingToken(DefaultAuthenticationFailureHandler.java:74) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$AuditableTransportRequest.anonymousAccessDenied(AuthenticationService.java:553) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$handleNullToken(AuthenticationService.java:363) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.handleNullToken(AuthenticationService.java:368) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.consumeToken(AuthenticationService.java:295) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$extractToken(AuthenticationService.java:267) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.extractToken(AuthenticationService.java:284) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$null(AuthenticationService.java:218) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.action.ActionListener.onResponse(ActionListener.java:59) ~[elasticsearch-5.6.16.jar:5.6.16] at org.elasticsearch.xpack.security.authc.TokenService.getAndValidateToken(TokenService.java:218) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$authenticateAsync(AuthenticationService.java:214) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$lookForExistingAuthentication(AuthenticationService.java:246) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lookForExistingAuthentication(AuthenticationService.java:257) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.authenticateAsync(AuthenticationService.java:210) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.access0(AuthenticationService.java:159) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.authc.AuthenticationService.authenticate(AuthenticationService.java:122) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.transport.ServerTransportFilter$NodeProfile.inbound(ServerTransportFilter.java:146) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.xpack.security.transport.SecurityServerTransportInterceptor$ProfileSecuredRequestHandler.messageReceived(SecurityServerTransportInterceptor.java:314) ~[x-pack-api-5.6.1.jar:5.6.1] at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:69) ~[elasticsearch-5.6.16.jar:5.6.16] at org.elasticsearch.transport.TcpTransport$RequestHandler.doRun(TcpTransport.java:1556) ~[elasticsearch-5.6.16.jar:5.6.16] at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) ~[elasticsearch-5.6.16.jar:5.6.16] at org.elasticsearch.common.util.concurrent.EsExecutors.execute(EsExecutors.java:110) ~[elasticsearch-5.6.16.jar:5.6.16] at org.elasticsearch.transport.TcpTransport.handleRequest(TcpTransport.java:1513) ~[elasticsearch-5.6.16.jar:5.6.16] at org.elasticsearch.transport.TcpTransport.messageReceived(TcpTransport.java:1396) ~[elasticsearch-5.6.16.jar:5.6.16] at org.elasticsearch.transport.netty4.Netty4MessageChannelHandler.channelRead(Netty4MessageChannelHandler.java:75) ~[transport-netty4-client-5.6.16.jar:5.6.16] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:297) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:413) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:241) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:544) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458) ~[netty-all-4.1.63.Final.jar:4.1.63.Final] at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858) ~[na:na] at java.lang.Thread.run(Thread.java:834) ~[na:1.8.0_275]
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)