我正在从Eclipse Milo客户端连接到Eclipse Milo服务器。一切正常,但是当我尝试连接除“None”以外的任何SecurityPolicy时,都会出现以下错误:

17:28:18.365 [main] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - connect(), currentState=NotConnected
17:28:18.365 [main] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - connect() while NotConnected
java.lang.Exception: null
    at org.eclipse.milo.opcua.stack.client.ClientChannelManager.connect(ClientChannelManager.java:67) [stack-client-0.2.3.jar:0.2.3]
    at org.eclipse.milo.opcua.stack.client.UaTcpStackClient.connect(UaTcpStackClient.java:127) [stack-client-0.2.3.jar:0.2.3]
    at org.eclipse.milo.opcua.sdk.client.OpcUaClient.connect(OpcUaClient.java:312) [sdk-client-0.2.3.jar:0.2.3]
    at de.dlh.lht.ticc.esa.opcua.client.lib.LhtOpcUaClient.connect(LhtOpcUaClient.java:86) [classes/:?]
    at de.dlh.lht.ticc.esa.opcua.client.lib.TestTools.runWithCredentials(TestTools.java:41) [test-classes/:?]
    at de.dlh.lht.ticc.esa.opcua.client.lib.ConnectAgainstMiloServerTest.credentialsTest(ConnectAgainstMiloServerTest.java:48) [test-classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_101]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_101]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_101]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_101]
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) [junit-4.12.jar:4.12]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) [junit-4.12.jar:4.12]
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) [junit-4.12.jar:4.12]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) [junit-4.12.jar:4.12]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12]
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) [junit-rt.jar:?]
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) [junit-rt.jar:?]
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) [junit-rt.jar:?]
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) [junit-rt.jar:?]
17:28:18.367 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - Channel bootstrap failed: null
java.nio.channels.ClosedChannelException: null

de.dlh.lht.ticc.esa.opcua.client.lib.exceptions.ClientExecutionException: java.util.concurrent.ExecutionException: java.nio.channels.ClosedChannelException

    at de.dlh.lht.ticc.esa.opcua.client.lib.LhtOpcUaClient.connect(LhtOpcUaClient.java:88)
    at de.dlh.lht.ticc.esa.opcua.client.lib.TestTools.runWithCredentials(TestTools.java:41)
    at de.dlh.lht.ticc.esa.opcua.client.lib.ConnectAgainstMiloServerTest.credentialsTest(ConnectAgainstMiloServerTest.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.util.concurrent.ExecutionException: java.nio.channels.ClosedChannelException
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
    at de.dlh.lht.ticc.esa.opcua.client.lib.LhtOpcUaClient.connect(LhtOpcUaClient.java:86)
    ... 24 more
Caused by: java.nio.channels.ClosedChannelException

任何想法?

当我使用带有私钥以及用户名/密码凭据的证书时,会发生这种情况。服务器端日志
DEBUG o.e.m.o.s.s.h.UaTcpServerAsymmetricHandler - Received CloseSecureChannelRequest
所以我认为客户就是这里的问题。其他opc-ua服务器也会发生相同的问题。

编辑:我创建了一个最小的示例,其中发生了错误
package de.dlh.lht.ticc.esa.opcua.client.lib;

import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.stack.client.UaTcpStackClient;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class SmokeTest {

    private static final Logger log = LoggerFactory.getLogger(SmokeTest.class);

    private static EndpointDescription getEndpointDescriptions(String endpoint, SecurityPolicy securityPolicy) throws Exception {

        EndpointDescription[] endpoints;

        try {
            endpoints = UaTcpStackClient
                    .getEndpoints(endpoint)
                    .get();
        } catch (Exception ex) {
            log.warn("failed to get endpoints", ex);
            log.warn("will try to explicitly discover endpoints");
            String discoveryUrl = endpoint + "/discovery";
            log.info("Trying explicit discovery URL: {}", discoveryUrl);
            endpoints = UaTcpStackClient
                    .getEndpoints(discoveryUrl)
                    .get();
        }
        EndpointDescription endpointDescription = Arrays.stream(endpoints)
                .filter(e -> e.getSecurityPolicyUri().equals(securityPolicy.getSecurityPolicyUri()))
                .findFirst().orElseThrow(() -> new Exception("no valid endpoint found for '" + endpoint + "'"));

        return endpointDescription;

    }

    @Test
    public void runTest() throws Exception {
        OpcUaClientConfigBuilder builder = OpcUaClientConfig.builder();
        EndpointDescription endpointDescription =
                getEndpointDescriptions("opc.tcp://127.0.0.1:12686/example", SecurityPolicy.Basic128Rsa15);

        builder
                .setEndpoint(endpointDescription);

        builder.setIdentityProvider(new UsernameProvider(
                "user",
                "password1"
        ));

        OpcUaClient client = new OpcUaClient(builder.build());
        client.connect().get();
        Thread.sleep(1000 * 10);
        client.disconnect().get();


    }

}

该测试针对Eclipse milo示例服务器运行:
https://github.com/eclipse/milo/blob/master/milo-examples/server-examples/src/main/java/org/eclipse/milo/examples/server/ExampleServer.java

另一个更新:
最让我烦恼的是以下行为
09:19:09.040 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.handlers.UaTcpClientMessageHandler - Received OpenSecureChannelResponse.
09:19:09.040 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.handlers.UaTcpClientMessageHandler - SecureChannel id=4, currentTokenId=4, previousTokenId=-1, lifetime=3600000ms, createdAt=DateTime{utcTime=131860523490250000, javaDate=Wed Nov 07 09:19:09 CET 2018}
09:19:09.040 [ua-netty-event-loop-0] DEBUG org.eclipse.milo.opcua.stack.client.handlers.UaTcpClientMessageHandler - 0 message(s) queued before handshake completed; sending now.
09:19:09.040 [ua-shared-pool-1] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - Channel bootstrap succeeded: localAddress=/127.0.0.1:50437, remoteAddress=/127.0.0.1:12686
09:19:09.134 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - disconnect(), currentState=Connected
09:19:09.134 [ua-shared-pool-1] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - Sending CloseSecureChannelRequest...

客户端连接似乎成功了,但是从上面的烟雾测试来看,客户端立即立即再次自行断开连接,而在不使用SecurityPolicy的情况下则不会这样做。

甚至更奇怪的是,此后,日志还会继续显示:
09:28:12.283 [ua-netty-event-loop-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - channelInactive(), disconnect complete
09:28:12.283 [ua-netty-event-loop-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - disconnect complete, state set to Idle
09:28:12.299 [main] INFO  org.eclipse.milo.opcua.sdk.client.OpcUaClient - Eclipse Milo OPC UA Stack version: 0.2.4
09:28:12.299 [main] INFO  org.eclipse.milo.opcua.sdk.client.OpcUaClient - Eclipse Milo OPC UA Client SDK version: 0.2.4
09:28:12.315 [main] DEBUG org.eclipse.milo.opcua.sdk.client.OpcUaClient - Added ServiceFaultListener: org.eclipse.milo.opcua.sdk.client.session.SessionFsm$FaultListener@333d4a8c
09:28:12.330 [main] DEBUG org.eclipse.milo.opcua.sdk.client.OpcUaClient - Added SessionActivityListener: org.eclipse.milo.opcua.sdk.client.subscriptions.OpcUaSubscriptionManager$1@71687585
09:28:12.440 [main] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - connect(), currentState=NotConnected
09:28:12.440 [main] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - connect() while NotConnected
java.lang.Exception: null
    at org.eclipse.milo.opcua.stack.client.ClientChannelManager.connect(ClientChannelManager.java:67) [stack-client-0.2.4.jar:0.2.4]
    at org.eclipse.milo.opcua.stack.client.UaTcpStackClient.connect(UaTcpStackClient.java:127) [stack-client-0.2.4.jar:0.2.4]
    at org.eclipse.milo.opcua.sdk.client.OpcUaClient.connect(OpcUaClient.java:312) [sdk-client-0.2.4.jar:0.2.4]
    at de.dlh.lht.ticc.esa.opcua.client.lib.SmokeManualTest.run(SmokeManualTest.java:95) [test-classes/:?]
    at de.dlh.lht.ticc.esa.opcua.client.lib.SmokeManualTest.credentialsTest(SmokeManualTest.java:104) [test-classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_101]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_101]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_101]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_101]
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) [junit-4.12.jar:4.12]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) [junit-4.12.jar:4.12]
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.12.jar:4.12]
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.12.jar:4.12]
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) [junit-4.12.jar:4.12]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) [junit-4.12.jar:4.12]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12]
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) [junit-rt.jar:?]
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) [junit-rt.jar:?]
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) [junit-rt.jar:?]
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) [junit-rt.jar:?]
09:28:12.440 [ua-shared-pool-0] DEBUG org.eclipse.milo.opcua.stack.client.ClientChannelManager - Channel bootstrap failed: null
java.nio.channels.ClosedChannelException: null

因此,看起来ClientChannelManager在自身触发的断开连接后尝试尝试连接。

我尝试过的另一件事是
builder.setCertificateValidator( new InsecureCertificateValidator());

假定自签名服务器证书被拒绝,但这没有帮助。甚至没有打印该类的日志,因此我假设未调用证书验证器,并且错误发生的时间更早。

只是为了好玩,我还添加了
static {
    CryptoRestrictions.remove();
    Security.addProvider(new BouncyCastleProvider());
}

对我的烟雾测试。还是没有运气

最佳答案

当然,这是一个非常简单的问题。日志中的其他错误与它无关。

再次查看Understanding OPC-UA Security using Eclipse Milo很有帮助。

请参阅,您在使用不是“无”的SecurityPolicy时总是需要应用程序证书,因为该证书用于消息加密和签名。它也是一个有点特殊的证书,因为它包含一个应用程序uri,必须与匹配,该urit是您通过builder.setApplicationUri()为客户端配置的应用程序uri。

通过证书使用身份验证时,您将提供一个第二证书(和私钥),用于在服务器上确认您的身份。这也是为什么您可以通过cert或用户名/密码通过进行身份验证的原因,而完全没有消息加密和对进行签名的原因

08-17 18:58