Определение модели ThingWorx в Composer > Система > Подсистемы > Подсистема передачи файлов > Дополнительное повышение безопасности для удаленных передач файлов
Дополнительное повышение безопасности для удаленных передач файлов
Для клиентов, которым требуются дополнительные меры контроля и безопасности, связанные с удаленными передачами файлов, PTC рекомендует реализовать некоторые или все из приведенных ниже сущностей и сопутствующую подписку.
Первая сущность - это "Структура данных", позволяющая администраторам конфигурировать необходимые параметры, чтобы получить требуемые частоту и размер удаленной передачи файлов. Структура данных позволяет конфигурировать нужным образом различные настройки для разных пользователей ThingWorx (и/или связанных с ними ключей приложений).
Вторая сущность - это "Поток значений", используемый для записи в журнал размера и частоты передачи файлов для каждого пользователя.
Третья сущность предназначена для реализации подписки, которая инициируется каждым событием удаленной передачи файлов. Подписка автоматически выполняет следующие действия.
1. Отправляет предупреждение.
2. Замораживает передачу файла.
3. Разрывает соответствующее соединение WebSocket при превышении определенной частоты передачи файла.
* 
В приведенных ниже примерах операторы средства ведения журнала закомментированы и предназначены только для отладки. PTC рекомендует пользователям не включать их в производственный процесс, чтобы избежать ненужного раскрытия информации.
Сущность "Структура данных"
Сначала импортируйте или создайте структуру данных, состоящую из трех полей: Size, User и Frequency. Это позволит отслеживать пределы максимально допустимого числа передач файлов пользователем.
<?xml version="1.0" encoding="UTF-8"?>
<!-- This entity is for informational and example purposes only, and you must configure/validate it to ensure that it meets your functional and security requirements. -->
<Entities build="latest" majorVersion="0" minorVersion="0" modelPersistenceProviderPackage="PostgresPersistenceProviderPackage" revision="0" schemaVersion="1045" universal="">
<DataShapes>
<DataShape baseDataShape="" description="DataShape for permissible file transfer limits" documentationContent="" homeMashup="" lastModifiedDate="2020-10-01T00:00:00.000-00:00" name="SizeLimits" projectName="FileTransfer" tags="">
<Owner name="Administrator" type="User" />
<avatar />
<DesignTimePermissions>
<Create />
<Read />
<Update />
<Delete />
<Metadata />
</DesignTimePermissions>
<RunTimePermissions />
<VisibilityPermissions>
<Visibility />
</VisibilityPermissions>
<ConfigurationTableDefinitions />
<ConfigurationTables />
<FieldDefinitions>
<FieldDefinition aspect.isPrimaryKey="false" aspect.minimumValue="1.0" baseType="NUMBER" description="" name="Frequency" ordinal="3" />
<FieldDefinition aspect.isPrimaryKey="false" aspect.minimumValue="1.0" baseType="NUMBER" description="SizeLimit for user in bytes" name="Size" ordinal="1" />
<FieldDefinition aspect.isPrimaryKey="false" baseType="STRING" description="User name" name="User" ordinal="2" />
</FieldDefinitions>
</DataShape>
</DataShapes>
</Entities>
Сущность "Поток значений"
После импорта или создания структуры данных импортируйте или создайте следующую сущность для занесения в журнал истории передачи файлов по каждому пользователю:
<?xml version="1.0" encoding="UTF-8"?>
<!-- This entity is for informational and example purposes only, and you must configure/validate it to ensure that it meets your functional and security requirements. -->
<Entities build="latest" majorVersion="0" minorVersion="0" modelPersistenceProviderPackage="PostgresPersistenceProviderPackage" revision="0" schemaVersion="1045" universal="">
<Things>
<Thing description="ValueStream to log history of file transfers" documentationContent="" effectiveThingPackage="ValueStreamThing" enabled="true" homeMashup="StreamMashup" identifier="" lastModifiedDate="2020-10-01T00:00:00.000-00:00" name="VS" projectName="FileTransfer" published="false" tags="" thingTemplate="ValueStream" valueStream="">
<Owner name="Administrator" type="User" />
<avatar />
<DesignTimePermissions>
<Create />
<Read />
<Update />
<Delete />
<Metadata />
</DesignTimePermissions>
<RunTimePermissions />
<VisibilityPermissions>
<Visibility />
</VisibilityPermissions>
<ConfigurationTableDefinitions />
<ConfigurationTables>
<ConfigurationTable description="Data Thing Configuration" isMultiRow="false" name="DataThingSettings" ordinal="0">
<DataShape>
<FieldDefinitions>
<FieldDefinition baseType="STRING" description="Persistence Provider Name" name="persistenceProvider" ordinal="0" />
</FieldDefinitions>
</DataShape>
<Rows>
<Row>
<persistenceProvider><![CDATA[ThingworxPersistenceProvider]]></persistenceProvider>
</Row>
</Rows>
</ConfigurationTable>
<ConfigurationTable description="Configurable options to tune Value Stream performance" isMultiRow="false" name="PersistenceProviderCustomSettings" ordinal="2">
<DataShape>
<FieldDefinitions>
<FieldDefinition aspect.friendlyName="Persistence Provider Custom Settings Table" baseType="INFOTABLE" description="Persistence Provider Custom Config Table" name="customConfigTable" ordinal="0" />
</FieldDefinitions>
</DataShape>
<Rows>
<Row>
<customConfigTable>
<infoTable>
<DataShape>
<FieldDefinitions />
</DataShape>
<Rows />
</infoTable>
</customConfigTable>
</Row>
</Rows>
</ConfigurationTable>
</ConfigurationTables>
<ThingShape>
<PropertyDefinitions />
<ServiceDefinitions />
<EventDefinitions />
<ServiceMappings />
<ServiceImplementations />
<Subscriptions />
</ThingShape>
<PropertyBindings />
<RemotePropertyBindings />
<RemoteServiceBindings />
<RemoteEventBindings />
<AlertConfigurations />
<ImplementedShapes />
<ThingProperties />
</Thing>
</Things>
</Entities>
Сущность "Передача удаленных файлов"
В заключение импортируйте или создайте вещь, содержащую приведенную ниже подписку, которая будет инициироваться при каждом событии передачи файлов:
<?xml version="1.0" encoding="UTF-8"?>
<!-- This entity is for informational and example purposes only, and you must configure/validate it to ensure that it meets your functional and security requirements. -->
<Entities build="latest" majorVersion="0" minorVersion="0" modelPersistenceProviderPackage="PostgresPersistenceProviderPackage" revision="0" schemaVersion="1045" universal="">
<Things>
<Thing description="Thing for regulating Remote File Transfer" documentationContent="" effectiveThingPackage="RemoteThingWithFileTransfer" enabled="true" homeMashup="" identifier="FileRepo@ServerA" lastModifiedDate="2020-10-01T00:00:00.000-00:00" name="RemoteFileTransfer" projectName="FileTransfer" published="false" tags="" thingTemplate="RemoteThingWithFileTransfer" valueStream="VS">
<Owner name="Administrator" type="User" />
<avatar />
<DesignTimePermissions>
<Create />
<Read />
<Update />
<Delete />
<Metadata />
</DesignTimePermissions>
<RunTimePermissions />
<VisibilityPermissions>
<Visibility />
</VisibilityPermissions>
<ConfigurationTableDefinitions />
<ConfigurationTables>
<ConfigurationTable description="Reporting Settings" isMultiRow="false" name="ReportingConfiguration" ordinal="0">
<DataShape>
<FieldDefinitions>
<FieldDefinition aspect.defaultValue="NotReporting" aspect.isPrimaryKey="true" aspect.isReadOnly="false" aspect.thingTemplate="ReportingStrategy" baseType="THINGNAME" description="Strategy to determine health" name="reportingStrategy" ordinal="0" />
</FieldDefinitions>
</DataShape>
<Rows>
<Row>
<reportingStrategy><![CDATA[AlwaysOnReporting]]></reportingStrategy>
</Row>
</Rows>
</ConfigurationTable>
</ConfigurationTables>
<ThingShape>
<PropertyDefinitions>
<PropertyDefinition aspect.cacheTime="0.0" aspect.dataChangeType="VALUE" aspect.isLogged="true" aspect.isPersistent="true" baseType="NUMBER" category="" description="" isLocalOnly="false" name="Administrator" ordinal="2" />
<PropertyDefinition aspect.cacheTime="0.0" aspect.dataChangeType="VALUE" aspect.defaultValue="0.0" aspect.isLogged="true" aspect.isPersistent="true" baseType="NUMBER" category="" description="" isLocalOnly="false" name="EventProp" ordinal="4" />
<PropertyDefinition aspect.cacheTime="0.0" aspect.dataChangeType="VALUE" aspect.dataShape="SizeLimits" aspect.isLogged="false" aspect.isPersistent="true" baseType="INFOTABLE" category="" description="" isLocalOnly="false" name="Users" ordinal="3" />
</PropertyDefinitions>
<ServiceDefinitions>
<ServiceDefinition aspect.isAsync="false" category="" description="" isAllowOverride="false" isLocalOnly="false" isOpen="false" isPrivate="false" name="s1">
<ResultType baseType="INFOTABLE" description="" name="result" ordinal="0" />
<ParameterDefinitions />
</ServiceDefinition>
</ServiceDefinitions>
<EventDefinitions />
<ServiceMappings />
<ServiceImplementations>
<ServiceImplementation description="" handlerName="Script" name="s1">
<ConfigurationTables>
<ConfigurationTable description="" isMultiRow="false" name="Script" ordinal="0">
<DataShape>
<FieldDefinitions>
<FieldDefinition baseType="STRING" description="code" name="code" ordinal="0" />
</FieldDefinitions>
</DataShape>
<Rows>
<Row>
<code><![CDATA[var ed = new Date();
var result = me.QueryNumberPropertyHistory({
oldestFirst: undefined /* BOOLEAN */,
maxItems: undefined /* NUMBER */,
endDate: ed /* DATETIME */,
propertyName: "Administrator" /* STRING */,
query: undefined /* QUERY */,
startDate: ed-(24*3600*1000) /* DATETIME */
});]]></code>
</Row>
</Rows>
</ConfigurationTable>
</ConfigurationTables>
</ServiceImplementation>
</ServiceImplementations>
<Subscriptions>
<Subscription description="" enabled="false" eventName="FileTransfer" name="FileTransferSub" source="" sourceProperty="" sourceType="Thing">
<ServiceImplementation description="" handlerName="Script" name="FileTransferSub">
<ConfigurationTables>
<ConfigurationTable description="" isMultiRow="false" name="Script" ordinal="0">
<DataShape>
<FieldDefinitions>
<FieldDefinition baseType="STRING" description="code" name="code" ordinal="0" />
</FieldDefinitions>
</DataShape>
<Rows>
<Row>
<code><![CDATA[var activeTransferJobs = Subsystems["FileTransferSubsystem"].GetActiveTransferJobs();
for each (activeTransferJob in activeTransferJobs.rows) {
var bytesTransferred = activeTransferJob.bytesTransferred;
var transferSize = activeTransferJob.maxSize;
//QueryPropertyHistoryfor24hours
var ed = new Date();
var user = eventData.user;
var last24HrsFileTransfer = me.QueryNumberPropertyHistory({
oldestFirst: undefined /* BOOLEAN */,
maxItems: undefined /* NUMBER */,
endDate: ed /* DATETIME */,
propertyName: user /* STRING */,
query: undefined /* QUERY */,
startDate: ed-(24*3600*1000) /* DATETIME */
});
//Aggregate for 24 hrs.
var totalTransferredBytes = Resources["InfoTableFunctions"].Aggregate({
t: last24HrsFileTransfer,
columns: "value",
aggregates: "SUM"
});
var totalFrequency = last24HrsFileTransfer.length;
var defaultSizeLimitForUser;
var defaultFrequencyForUser;
for each(var user in me.Users.rows){
if(user.User == eventData.user){
defaultSizeLimitForUser = user.Size;
defaultFrequencyForUser = user.Frequency;
}
}
if(totalFrequency>defaultFrequencyForUser || (totalTransferredBytes.SUM_value + transferSize)> defaultSizeLimitForUser){
//logger.error("File Transfer Limit Exceeded : " + activeTransferJob.transferId);
//Send Alert
var eventPropValue = Things['RemoteFileTransfer']['EventProp'];
Things['RemoteFileTransfer']['EventProp'] = eventPropValue + 1;

//Freeze Transfer
//logger.warn("FreezingTransfer : " + activeTransferJob.transferId);
Subsystems["FileTransferSubsystem"].CancelTransfer({
reason: "Surpassed file transfer limit of : " + defaultSizeLimitForUser + " bytes or frequency of " + defaultFrequencyForUser,
transferId: activeTransferJob.transferId
});
//logger.warn("Transfer Freezed : " + activeTransferJob.transferId);
//Closing Endpoint Session for User
result = Subsystems["WSCommunicationsSubsystem"].CloseEndpointSessions({
userName: activeTransferJob.user
});
//logger.warn("Session Closed for userContext : " + activeTransferJob.user);
}
me[eventData.user] = bytesTransferred;
}]]></code>
</Row>
</Rows>
</ConfigurationTable>
</ConfigurationTables>
</ServiceImplementation>
</Subscription>
</Subscriptions>
</ThingShape>
<PropertyBindings />
<RemotePropertyBindings />
<RemoteServiceBindings />
<RemoteEventBindings />
<AlertConfigurations>
<AlertDefinitions name="Administrator" />
<AlertDefinitions name="EventProp" />
<AlertDefinitions name="Users" />
</AlertConfigurations>
<ImplementedShapes />
<ThingProperties>
<Users>
<Value>
<infoTable>
<DataShape>
<FieldDefinitions>
<FieldDefinition aspect.isPrimaryKey="false" aspect.minimumValue="1.0" baseType="NUMBER" description="" name="Frequency" ordinal="3" />
<FieldDefinition aspect.isPrimaryKey="false" aspect.minimumValue="1.0" baseType="NUMBER" description="SizeLimit for user in bytes" name="Size" ordinal="1" />
<FieldDefinition aspect.isPrimaryKey="false" baseType="STRING" description="User name" name="User" ordinal="2" />
</FieldDefinitions>
</DataShape>
<Rows>
<Row>
<Frequency>10.0</Frequency>
<Size>1500000.0</Size>
<User><![CDATA[Administrator]]></User>
</Row>
</Rows>
</infoTable>
</Value>
<Timestamp>2020-10-01T00:00:00.000-00:00</Timestamp>
<Quality>GOOD</Quality>
</Users>
</ThingProperties>
</Thing>
</Things>
</Entities>
Было ли это полезно?