如何在Node-Opcua服务器中获得连接的客户端和客户端证书

时间:2019-08-16 16:03:18

标签: opc opc-ua node-opcua

我有一个节点opcua服务器设置,其中连接了2个客户端,并且安全模式设置为SignAndEncrypt。现在,我有两个问题:

  1. 服务器是否可以找到与之连接的客户端数量?
  2. 服务器应用程序想知道已连接客户端的身份,是否有API可以获取在OpenSecureChannel期间获得的客户端证书?

1 个答案:

答案 0 :(得分:0)

OPCUA服务器可以在RootFolder.Server.ServerDiagnostics节点下公开此类信息,您需要的信息可以通过OPCUA访问。

这个小节点操作客户端程序将向您展示如何操作。

注意:

  • 某些数据(例如安全诊断程序)需要安全的连接和非匿名用户

client_extract_server_diagnostic.ts

// this script is typescript and can be run this way
// $ npx ts-node client_extract_server_diagnostic.ts

import { 
    AttributeIds,
    OPCUAClient,
    ClientSession, 
    StatusCodes,
    MessageSecurityMode,
    SecurityPolicy,
    UserIdentityInfoUserName,
    UserTokenType   
} from "node-opcua";

// the opcua server to connect to
const endpointUrl = "opc.tcp://localhost:48010";

// the credential 
const userIdentityToken: UserIdentityInfoUserName = {
    password: "secret",
    userName: "root",
    type: UserTokenType.UserName
};

async function extractServerStatistics(session: ClientSession) {

    const nodesToRead = [
        { 
            attributeIds: AttributeIds.Value, nodeId:"Server_ServerDiagnostics_EnabledFlag" 
        },
        { 
            attributeIds: AttributeIds.Value, nodeId:"Server_ServerDiagnostics_ServerDiagnosticsSummary_CurrentSessionCount" //i=2277 
        },
        {
            attributeIds: AttributeIds.Value, nodeId:"Server_ServerDiagnostics_ServerDiagnosticsSummary_CurrentSubscriptionCount" // i=2285 
        },
        {
            attributeIds: AttributeIds.Value, nodeId: "Server_ServerDiagnostics_ServerDiagnosticsSummary_CumulatedSessionCount" // i=2278 
        },
        {
            attributeIds: AttributeIds.Value, nodeId: "Server_ServerDiagnostics_ServerDiagnosticsSummary_CumulatedSubscriptionCount" // i=2278 
        },
        {
            attributeIds: AttributeIds.Value, nodeId: "Server_ServerDiagnostics_SessionsDiagnosticsSummary_SessionSecurityDiagnosticsArray" // i=3708 
        }

    ];
    const dataValues = await session.read(nodesToRead);

    console.log("Diagnostic enabled ?         = ", dataValues[0].value.value);
    console.log("Current Session Count        = ", dataValues[1].value.value);
    console.log("Current Subscription Count   = ", dataValues[2].value.value);
    console.log("Cumulated Session Count      = ", dataValues[3].value.value);
    console.log("Cumulated Subscription Count = ", dataValues[4].value.value);

    // note reading SessionSecurityDiagnotiscArray may requires authenticated session to succeed
    console.log("SessionSecurityDiagnotiscArray       = ");

    if (dataValues[5].statusCode === StatusCodes.Good) {
        const sessionSecurityDiagnosticArray = dataValues[5].value.value;
        // console.log(dataValues[5].value.value.toString());
        for (const sessionSecurityDiagnostic of sessionSecurityDiagnosticArray)  {
            console.log(" session client certificate ", sessionSecurityDiagnostic.clientCertificate.toString("base64"));
            console.log();
        }
    } else {
        console.log(dataValues[5].toString());
    }
}
( async () => {

    try {
        const client = OPCUAClient.create({
            endpoint_must_exist: false,
            securityMode: MessageSecurityMode.SignAndEncrypt,
            securityPolicy: SecurityPolicy.Basic256Sha256,

        });
        client.on("backoff",() => console.log("still trying to connec to ", endpointUrl));

        await client.connect(endpointUrl);

        const session = await client.createSession(userIdentityToken);

        await extractServerStatistics(session);

        await session.close();
        await client.disconnect();
        console.log("done");
    } catch(err) {
        console.log("Err" , err.message);
        process.exit(1);
    }
})();