如何在 node-opcua 服务器中获取连接的客户端和客户端证书
How to get connected clients and client certificate in node-opcua server
我有一个 node-opcua 服务器设置,有 2 个客户端连接到它,安全模式设置为 SignAndEncrypt。现在,我有 2 个问题:
- 有没有办法让服务器知道有多少客户端连接到它?
- 服务器应用程序想知道连接的客户端的身份,是否有 API 来获取在 OpenSecureChannel 期间获得的客户端证书?
OPCUA Server可以在RootFolder.Server.ServerDiagnostics
节点下暴露这些信息,您需要的信息应该可以通过OPCUA访问。
这个小的 node-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);
}
})();
我有一个 node-opcua 服务器设置,有 2 个客户端连接到它,安全模式设置为 SignAndEncrypt。现在,我有 2 个问题:
- 有没有办法让服务器知道有多少客户端连接到它?
- 服务器应用程序想知道连接的客户端的身份,是否有 API 来获取在 OpenSecureChannel 期间获得的客户端证书?
OPCUA Server可以在RootFolder.Server.ServerDiagnostics
节点下暴露这些信息,您需要的信息应该可以通过OPCUA访问。
这个小的 node-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);
}
})();