Konsy
Konsy

Reputation: 49

How to get connected clients and client certificate in node-opcua server

I have a node-opcua server setup with 2 clients connected to it with Security Mode set to SignAndEncrypt. Now, I have 2 questions:

  1. Is there a way for the server to find out how many clients are connected to it?
  2. The server application will like to know the identity of a connected client, is there an API to get the client certificate obtained during OpenSecureChannel?

Upvotes: 2

Views: 1855

Answers (1)

Etienne
Etienne

Reputation: 16867

OPCUA Server can expose such information under the RootFolder.Server.ServerDiagnostics node, and the information you need shall be accessible through OPCUA.

This little node-opcua client program will show you how to do.

note:

  • that certain data such as security diagnostics requires a secure connection and a non-anonymous user

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);
    }
})();

Upvotes: 2

Related Questions