Tutorial: Durchsuchen von Dateianlagen mit einem Antivirenprogramm
[AEM Forms]{class="badge positive" title="Gilt für AEM Forms"}
Die Funktion „File Attachment Virus Scanner / Validator“ ist im Early-Adopter-Programm enthalten. Sie können von Ihrer offiziellen E-Mail-Adresse aus an aem-forms-ea@adobe.com schreiben, um dem Early-Adopter-Programm beizutreten und den Zugriff auf diese Funktion zu beantragen.
Dieses Tutorial führt Sie durch den gesamten Prozess. Sie führen die ClamAV-Antiviren-Engine aus, fügen einen benutzerdefinierten Validator zu AEM hinzu, erstellen ein Beispiel für ein adaptives Formular mit einem Feld zum Hochladen von Dateien, verbinden den Validator und bestätigen, dass infizierte Dateien beim Senden zurückgewiesen werden. Es ist so geschrieben, dass es befolgt wird, auch wenn Sie neu in AEM sind. Alle Befehle, Bildschirmpfade und Werte, die Sie benötigen, werden angegeben.
Die Konzepte hinter dem Validator und die Schnittstellenreferenz finden Sie im Begleitartikel Scannen von Dateianlagen in adaptivem Forms mit einem benutzerdefinierten Validator. Sie müssen es nicht zuerst lesen, um dieses Tutorial abzuschließen, aber es erklärt, warum jedes Stück existiert.
Was Sie erstellen werden what-you-will-build
Am Ende haben Sie:
- Ein laufender ClamAV-Daemon (
clamd), der Dateien auf Anfrage scannt. - Ein benutzerdefinierter AEM-Dienst (der ClamAV-Scanner), der jede hochgeladene Datei an
clamdsendet und infizierte Dateien zurückweist. - Ein Beispiel für ein adaptives Formular mit dem Namen File Attachment Scanner mit einem Feld „Datei-Upload“ und einer Schaltfläche „Senden“.
- Funktionstest: Eine normale Datei wird erfolgreich gesendet, und eine bekannte Testvirusdatei wird blockiert.
Bevor Sie beginnen: Annahmen und Voraussetzungen assumptions
In diesem Tutorial wird von der folgenden Einrichtung ausgegangen. Wenn ein Element fehlt, installieren oder beziehen Sie es, bevor Sie beginnen. Zu jedem Element gehört, wie es überprüft wird.
http://localhost:4502 erreichbar.http://localhost:4502 in einem Browser. Der AEM-Anmelde- oder Startbildschirm sollte angezeigt werden.http://localhost:4502 mit einem Administratorkonto an (die standardmäßigen lokalen Anmeldeinformationen sind admin/admin)FT_FORMS-23497 istFileAttachmentValidatorManager. Das Feld der Registerkarte „Übermittlung“ selbst wird in diesem Tutorial in Schritt 7 hinzugefügt. So oder so ist es nicht vorkonfiguriert.ui.apps-Modul Ihres Projekts einen Container Proxy Komponente) für adaptive Formulare oder können ihn erstellenjava -version in einem Terminal ausführenmvn -version aus.docker --version aus.com.adobe.forms.common.service bereitstelltaem-forms-addon-sdk-<version>.zip vom Adobe Software Distribution-Portal herunterladen (Early-Adopter-Programmberechtigung erforderlich)Zu ersetzende Werte substitute-values
Wo immer Sie diese Platzhalter sehen, ersetzen Sie sie durch Ihre eigenen Werte:
<PROJECT_ROOT>: Der Ordner Ihres AEM Maven-Projekts.<APP_ID>: Die Anwendungs-ID oder der Bundle-Modulname Ihres Projekts (z. B.mysite).<SDK_DEPENDENCY_VERSION>: Die in der heruntergeladenen SDK gebündelteadobe-xfaforms-common(Gruppen-ID und Artefakt-ID sind fest; siehe Schritt 3).
Fahrplan roadmap
Sie führen diese Schritte in der folgenden Reihenfolge aus:
- Starten Sie einen ClamAV-Daemon (
clamd). - Einrichten eines AEM Maven-Projekts (überspringen Sie diesen Schritt, wenn Sie bereits über eines verfügen).
- Fügen Sie die Early Access-Abhängigkeit hinzu.
- Fügen Sie die Klasse ClamAV-Validator hinzu.
- Erstellen und Bereitstellen für AEM.
- Konfigurieren Sie die
clamdin AEM. - Fügen Sie das Feld Validator zum Dialogfeld Formular hinzu.
- Erstellen Sie das Beispiel für ein adaptives Formular.
- Verbinden Sie den ClamAV-Scanner mit dem Formular.
- Testen Sie mit einer sauberen Datei und einer Testvirusdatei.
Schritt 1: ClamAV-Daemon starten step-1-clamd
ClamAV wird als Hintergrund-Service namens clamd ausgeführt. Der von Ihnen erstellte Validator streamt jede hochgeladene Datei an clamd, der OK auf eine bereinigte Datei antwortet oder den Namen der Bedrohung meldet, wenn er eine entdeckt.
Der schnellste Weg, clamd zum Laufen zu bringen, ist Docker.
-
ClamAV starten:
code language-none docker run -d --name clamav -p 3310:3310 clamav/clamav:latestnote NOTE Auf Apple-Chip-Macs (arm64) verfügt dieses Image über keinen nativen arm64-Build und der obige Befehl schlägt mit no matching manifest for linux/arm64/v8fehl. Fügen Sie--platform linux/amd64hinzu, um sie stattdessen unter Emulation auszuführen:code language-none docker run -d --name clamav --platform linux/amd64 -p 3310:3310 clamav/clamav:latest -
Warte, bis er fertig ist. Beim ersten Start lädt es die Virendatenbank herunter, was einige Minuten dauern kann. Überwachen Sie die Protokolle, bis die Datenbank geladen wurde und
clamdabhört:code language-none docker logs -f clamavDrücken Sie
Ctrl+C, um die Verfolgung der Protokolle zu stoppen, sobald sie bereit ist. -
Stellen Sie sicher, dass
clamdüber Port3310erreichbar ist:code language-none printf 'PING\n' | nc localhost 3310Erwartetes Ergebnis: Die Antwort ist
PONG.
clamd-Daemon und den TCP-Socket auf Port 3310 in clamd.conf, aktualisieren Sie die Datenbank mit freshclam und starten Sie clamd. Führen Sie dann die Überprüfung in Schritt 3 oben durch.clamd wird als eigener Prozess ausgeführt, der von AEM getrennt ist. Dieses lokale Setup dient der Entwicklung. Auf AEM as a Cloud Service können Sie clamd nicht auf dem AEM-Host ausführen. Daher führen Sie es in realen Umgebungen als gemeinsamen oder externen Service aus und verweisen Sie den Validator darauf. Eine gemeinsame Instanz in derselben Region sollte bevorzugt werden, um Dateiinhalte in Ihrer Umgebung für die Datenresidenz und die Einhaltung von Vorschriften zu speichern.Schritt 2: Einrichten eines AEM Maven-Projekts step-2-project
Benutzerdefinierter Java-Code wird in AEM als Bundle bereitgestellt, das von einem Maven-Projekt erstellt wurde. Wenn Sie bereits über ein AEM-Projekt verfügen, fahren Sie mit Schritt 3 fort und verwenden Sie das Bundle-Modul (häufig mit dem Namen core).
Wenn Sie noch kein solches Projekt haben, erstellen Sie ein Projekt mit dem AEM-Projektarchetyp:
-
Wechseln Sie in einem Terminal in den Ordner, in dem Sie Code speichern, und führen Sie den Archetyp aus. Ersetzen Sie
<APP_ID>durch einen kurzen Namen in Kleinbuchstaben, z. B.mysite:code language-none mvn -B org.apache.maven.plugins:maven-archetype-plugin:generate -D archetypeGroupId=com.adobe.aem -D archetypeArtifactId=aem-project-archetype -D archetypeVersion=LATEST -D appId=<APP_ID> -D appTitle="<APP_ID>" -D name="<APP_ID>" -D groupId=com.example -D artifactId=<APP_ID> -D aemVersion=cloudErwartetes Ergebnis: ein neues
<APP_ID>(dies ist Ihr<PROJECT_ROOT>), das Module wiecore,ui.appsundallenthält. -
Der Java-Code, den Sie später hinzufügen, wird im
core-Modul unter folgendem Pfad eingefügt:code language-none <PROJECT_ROOT>/core/src/main/java/
core.Schritt 3: Frühzeitige Zugriffs-Abhängigkeit hinzufügen step-3-dependency
Der Code wird anhand der FileAttachmentValidator-Schnittstelle kompiliert, die von com.adobe.forms.foundation:adobe-xfaforms-common stammt (#9). Diese Abhängigkeit wird nicht in einem öffentlichen Maven-Repository veröffentlicht. Sie wird gebündelt im AEM Forms-Add-on SDK ausgeliefert, sodass Sie sie von dort extrahieren und in Ihr lokales Maven-Repository installieren können.
-
Laden Sie den neuesten verfügbaren Build von
aem-forms-addon-sdk-<version>.zipvom Adobe Software Distribution-Portal (Berechtigung für Early-Adopter-Programm erforderlich) herunter. Verwenden Sie immer den neuesten Build. Frühere Builds enthalten diese Abhängigkeit möglicherweise noch nicht. -
Extrahieren Sie die Abhängigkeits-JAR-Datei. Die SDK-ZIP-Datei enthält ein Funktionsarchiv (
.far), und das JAR ist darin gebündelt:code language-none unzip -p aem-forms-addon-sdk-<version>.zip aem-forms-addon-<version>.far > addon.far unzip -l addon.far | grep adobe-xfaforms-commonDer zweite Befehl zeigt den genauen JAR-Pfad und die Version an, die im Download enthalten sind, z. B.
com/adobe/forms/foundation/adobe-xfaforms-common/<version>/adobe-xfaforms-common-<version>.jar. Verwenden Sie diesen Pfad und diese Version im nächsten Schritt.code language-none unzip -p addon.far "com/adobe/forms/foundation/adobe-xfaforms-common/<version>/adobe-xfaforms-common-<version>.jar" > adobe-xfaforms-common.jar -
Installieren Sie die extrahierte JAR-Datei in Ihrem lokalen Maven-Repository, damit
pom.xmlsie beheben können.-DgeneratePom=trueeinschließen: In JAR wird ein eigenes internes Adobe-Build-POM mit einem übergeordneten Verweis eingebettet, den Ihr Projekt nicht auflösen kann. Dieses Flag ersetzt es durch ein sauberes, in sich abgeschlossenes:code language-none mvn install:install-file -Dfile=adobe-xfaforms-common.jar -DgroupId=com.adobe.forms.foundation -DartifactId=adobe-xfaforms-common -Dversion=<version> -Dpackaging=jar -DgeneratePom=true -
Öffnen Sie
<PROJECT_ROOT>/core/pom.xml. -
Fügen Sie im Abschnitt
<dependencies>die Abhängigkeit mit derselben Version hinzu, die Sie gerade installiert haben. Verwenden SieprovidedBereich, da die Schnittstelle zur Laufzeit von AEM bereitgestellt wird:code language-xml <dependency> <groupId>com.adobe.forms.foundation</groupId> <artifactId>adobe-xfaforms-common</artifactId> <version><SDK_DEPENDENCY_VERSION></version> <scope>provided</scope> </dependency> -
Speichern Sie die Datei.
Schritt 4: Hinzufügen der ClamAV-Validatorklasse step-4-class
-
Erstellen Sie eine neue Datei unter:
code language-none <PROJECT_ROOT>/core/src/main/java/com/example/forms/security/ClamAVFileAttachmentValidator.javaErstellen Sie die
forms/securityOrdner, falls sie noch nicht vorhanden sind. Sie können Ihren eigenen Paketnamen verwenden. Ändern Sie in diesem Fall diepackageentsprechend. -
Fügen Sie den folgenden Code ein:
code language-java package com.example.forms.security; import com.adobe.forms.common.service.FileAttachmentValidator; import com.adobe.forms.common.service.FileAttachmentValidationResult; import com.adobe.forms.common.service.FileAttachmentWrapper; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.Designate; import org.osgi.service.metatype.annotations.ObjectClassDefinition; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.charset.StandardCharsets; @Component(service = FileAttachmentValidator.class) @Designate(ocd = ClamAVFileAttachmentValidator.Config.class) public class ClamAVFileAttachmentValidator implements FileAttachmentValidator { @ObjectClassDefinition(name = "ClamAV File Attachment Scanner") public @interface Config { @AttributeDefinition(name = "clamd Host") String clamd_host() default "localhost"; @AttributeDefinition(name = "clamd Port") int clamd_port() default 3310; @AttributeDefinition(name = "Scan Timeout (ms)") int clamd_timeout() default 30000; } private static final String VALIDATOR_NAME = "ClamAV Scanner"; private static final int CHUNK_SIZE = 8192; private String host; private int port; private int timeout; @Activate protected void activate(Config config) { this.host = config.clamd_host(); this.port = config.clamd_port(); this.timeout = config.clamd_timeout(); } @Override public FileAttachmentValidationResult validateFileAttachment(FileAttachmentWrapper wrapper) { if (wrapper == null) { return new FileAttachmentValidationResult(false, "No attachment was received.", wrapper); } byte[] content = wrapper.getValue(); if (content == null || content.length == 0) { return new FileAttachmentValidationResult(false, "The attached file is empty.", wrapper); } try { String response = scan(content); if (response.endsWith("OK")) { return new FileAttachmentValidationResult(true, "File passed the virus scan.", wrapper); } if (response.contains("FOUND")) { return new FileAttachmentValidationResult(false, "A virus was detected in the attached file. Upload was rejected.", wrapper); } return new FileAttachmentValidationResult(false, "The file could not be scanned. Please try again later.", wrapper); } catch (Exception e) { // Fail closed: reject when clamd is unreachable rather than accept an unscanned file. return new FileAttachmentValidationResult(false, "The virus scanner is unavailable. Please try again later.", wrapper); } } /** * Streams the file to clamd using the INSTREAM command and returns the daemon's response. */ private String scan(byte[] data) throws Exception { try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port), timeout); socket.setSoTimeout(timeout); try (OutputStream raw = socket.getOutputStream(); DataOutputStream out = new DataOutputStream(raw); InputStream in = socket.getInputStream()) { out.writeBytes("zINSTREAM\0"); for (int offset = 0; offset < data.length; offset += CHUNK_SIZE) { int len = Math.min(CHUNK_SIZE, data.length - offset); out.writeInt(len); out.write(data, offset, len); } out.writeInt(0); // zero-length chunk signals end of stream out.flush(); ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream(); byte[] buffer = new byte[512]; int read; while ((read = in.read(buffer)) != -1) { responseBuffer.write(buffer, 0, read); } return responseBuffer.toString(StandardCharsets.US_ASCII.name()).trim(); } } } @Override public String getFileAttachmentValidatorName() { return VALIDATOR_NAME; } } -
Speichern Sie die Datei.
Schritt 5: Erstellen und Bereitstellen in AEM step-5-deploy
-
Wenn AEM ausgeführt wird (#1), erstellen Sie und stellen Sie über Ihren Projektstamm bereit. Mit diesem Befehl wird das Bundle in der lokalen Autoreninstanz installiert:
code language-none cd <PROJECT_ROOT> mvn clean install -PautoInstallBundleErwartetes Ergebnis: Build endet mit
BUILD SUCCESS. -
Bestätigen Sie, dass der Dienst ausgeführt wird. Öffnen Sie die Komponentenkonsole:
code language-none http://localhost:4502/system/console/componentsDiese Seite verfügt über kein integriertes Suchfeld: Verwenden Sie bei mehr als 5.000 aufgelisteten Komponenten die eigene Suchseite Ihres Browsers (Befehl+F oder Strg+F) und suchen Sie nach
ClamAVFileAttachmentValidator.Erwartetes Ergebnis: die Komponente aufgeführt wird und ihr Status "" (oder ""). Wenn er nicht zufrieden ist, lesen Sie Fehlerbehebung.
Schritt 6: Clad-Verbindung konfigurieren step-6-config
Teilen Sie dem Validator mit, wo clamd ist. Für die lokale Entwicklung stimmen die Standardwerte (localhost:3310) bereits mit Schritt 1 überein, sodass dieser Schritt nur erforderlich ist, wenn sich Ihre Werte unterscheiden. Einmal durchführen, um zu bestätigen, dass die Einstellungen existieren.
-
Öffnen Sie die Konfigurationskonsole:
code language-none http://localhost:4502/system/console/configMgr -
Diese Seite verfügt auch über kein integriertes Suchfeld: Verwenden Sie die Suchseite Ihres Browsers (Befehl+F oder Strg+F) für ClamAV File Attachment Scanner und öffnen Sie sie.
-
Bestätigen oder festlegen:
table 0-row-2 1-row-2 2-row-2 3-row-2 Einstellung Wert für dieses Tutorial klamme Wirt localhostKlammerauslass 3310Scan-Zeitüberschreitung (ms) 30000
-
Wählen Sie Speichern aus.
.cfg.json-Datei pro Umgebung), damit sie mit jeder Bereitstellung übertragen werden, anstatt von Hand festgelegt zu werden.Schritt 7: Hinzufügen des Validierungsfelds zum Dialogfeld „Formular“ step-7-dialog-field
Das Feld Dateianhang-Virenscanner/) ist im vorkonfigurierten Dialogfeld Container für adaptive Formulare nicht vorhanden. Bei auf Kernkomponenten basierenden Formularen fügen Sie sie einmal in Ihrem eigenen Projekt hinzu. Dies ist ein einmaliger Schritt. Sie wiederholen ihn nicht, wenn Sie später weitere Validatoren hinzufügen.
-
Wenn Ihre
formcontainer-Proxy-Komponente noch nicht vorhanden ist, erstellen Sie sie unter:code language-none <PROJECT_ROOT>/ui.apps/src/main/content/jcr_root/apps/<APP_ID>/components/adaptiveForm/formcontainer/.content.xmlcode language-xml <?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" jcr:primaryType="cq:Component" jcr:title="Form Container" sling:resourceSuperType="core/fd/components/form/container/v2/container"/>Wenn Sie diese Komponente bereits haben (die meisten Projekte, die aus dem Kernkomponenten-Archetyp erstellt wurden, tun dies), fahren Sie mit dem nächsten Schritt fort.
-
Erstellen Sie eine Dialogfelderweiterung unter:
code language-none <PROJECT_ROOT>/ui.apps/src/main/content/jcr_root/apps/<APP_ID>/components/adaptiveForm/formcontainer/_cq_dialog/.content.xmlcode language-xml <?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" jcr:primaryType="nt:unstructured"> <content jcr:primaryType="nt:unstructured"> <items jcr:primaryType="nt:unstructured"> <tabs jcr:primaryType="nt:unstructured"> <items jcr:primaryType="nt:unstructured"> <submitActions jcr:primaryType="nt:unstructured"> <items jcr:primaryType="nt:unstructured"> <columns jcr:primaryType="nt:unstructured"> <items jcr:primaryType="nt:unstructured"> <fileAttachmentValidator jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/select" fieldLabel="File Attachment Virus Scanner/Validator" fieldDescription="Select a registered validator configuration to scan submitted file attachments. Select None to disable validation for this form." emptyText="None" name="./fileAttachmentValidator"> <datasource jcr:primaryType="nt:unstructured" sling:resourceType="<APP_ID>/datasources/fileattachmentvalidators"/> </fileAttachmentValidator> </items> </columns> </items> </submitActions> </items> </tabs> </items> </content> </jcr:root>Dadurch wird nur das eine neue Feld definiert, wobei die Knotennamen des echten Dialogfelds bis zur Einfügemarke gespiegelt werden. Die vorhandenen Felder der Registerkarte „Übermittlung“ werden nicht neu definiert oder ersetzt. Warum funktioniert, erfahren Sie im Begleitartikel Dialogfeld „Hinzufügen des Validierungsfelds zum Formular“.
-
Fügen Sie das Datenquellen-Servlet hinzu, das Ihre registrierten Validatoren auflistet. Er ist unabhängig davon, welche Validator-Engine Sie verwenden. Siehe Hinzufügen des Validator-Felds zum Formular-Dialogfeld im Begleitartikel, um zu erfahren, was und warum er tut. Erstellen Sie sie unter:
code language-none <PROJECT_ROOT>/core/src/main/java/com/example/forms/security/FileAttachmentValidatorDataSourceServlet.javacode language-java package com.example.forms.security; import com.adobe.forms.common.service.FileAttachmentValidator; import com.adobe.forms.common.service.FileAttachmentValidatorManager; import com.adobe.granite.ui.components.ds.DataSource; import com.adobe.granite.ui.components.ds.SimpleDataSource; import com.adobe.granite.ui.components.ds.ValueMapResource; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceMetadata; import org.apache.sling.api.servlets.HttpConstants; import org.apache.sling.api.servlets.SlingSafeMethodsServlet; import org.apache.sling.api.wrappers.ValueMapDecorator; import org.apache.sling.servlets.annotations.SlingServletResourceTypes; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicy; import javax.servlet.Servlet; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Component(service = { Servlet.class }) @SlingServletResourceTypes( resourceTypes = "<APP_ID>/datasources/fileattachmentvalidators", methods = HttpConstants.METHOD_GET) public class FileAttachmentValidatorDataSourceServlet extends SlingSafeMethodsServlet { @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) private volatile FileAttachmentValidatorManager fileAttachmentValidatorManager; @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) { List<Resource> options = new ArrayList<>(); FileAttachmentValidatorManager manager = fileAttachmentValidatorManager; if (manager != null) { List<FileAttachmentValidator> validators = manager.getValidators(); if (validators != null) { for (FileAttachmentValidator validator : validators) { String name = validator.getFileAttachmentValidatorName(); if (name != null && !name.isEmpty()) { options.add(createOption(request, name)); } } } } DataSource dataSource = new SimpleDataSource(options.iterator()); request.setAttribute(DataSource.class.getName(), dataSource); } private Resource createOption(SlingHttpServletRequest request, String name) { Map<String, Object> props = new HashMap<>(); props.put("value", name); props.put("text", name); return new ValueMapResource(request.getResourceResolver(), new ResourceMetadata(), "nt:unstructured", new ValueMapDecorator(props)); } }Ersetzen Sie
<APP_ID>sowohl im XML-Dialogfeld als auch imresourceTypesdes Servlets mit der tatsächlichen Anwendungs-ID Ihres Projekts (übereinstimmender #4) und passen Sie den Paketnamen an, wenn sich Ihre Angaben von Schritt 4 unterscheiden. -
Erstellen und stellen Sie beide Änderungen bereit. Sie haben Inhalt (das Dialogfeld) und Code (das Servlet) geändert. Verwenden Sie daher beide Profile gemeinsam:
autoInstallPackageallein stellt nur den Inhalt bereit und lässt das Paket des Servlets nicht erneut bereitgestellt.code language-none cd <PROJECT_ROOT> mvn clean install -PautoInstallPackage,autoInstallBundleErwartetes Ergebnis: Der Build endet mit
BUILD SUCCESS, und dasui.appsInhaltspaket (einschließlich dieser Dialogfeldänderung) und dascore-Bundle (einschließlich des neuen Servlets) sind beide installiert.
FileAttachmentValidator wird automatisch in der Dropdown-Liste angezeigt, da jedes über eine eigene getFileAttachmentValidatorName() verfügt, und emptyText="None" behält „Kein Validator“ als Standard bei, sodass vorhandene Formulare nicht betroffen sind, bis Sie eines explizit auswählen.Schritt 8: Adaptives Beispielformular erstellen step-8-form
Erstellen Sie jetzt ein einfaches Formular mit einem Feld „Datei-Upload“.
-
Öffnen von Forms und Dokumenten:
code language-none http://localhost:4502/aem/forms.html/content/dam/formsanddocuments -
Wählen Erstellen (oben rechts) und dann Adaptives Formular aus.
-
Wählen Sie eine Vorlage aus der Galerie aus. Die Grundlage ist keine separate Frage: Sie ist Teil der von Ihnen ausgewählten Vorlage und wird als kleiner Untertitel unter dem Namen jeder Vorlage angezeigt (z. B. adaptives Formular (Kernkomponenten).
note important IMPORTANT Mehrere Vorlagen werden alle als leeres Formular bezeichnet: eine für Kernkomponenten, eine für Foundation-Komponenten, eine für Edge Delivery Services. Das Auswählen des falschen ist leicht zu übersehen und schlägt leise fehl: Der Rest dieses Tutorials scheint weiterhin zu funktionieren, aber das Feld Dateianhang-Virenscanner / -Validator wird nie aufgerufen, da diese Pipeline nur für Kernkomponenten-basierte Formulare vorhanden ist. Bestätigen Sie, dass der Untertitel Adaptives Formular (Kernkomponenten)) lautet bevor Sie fortfahren. -
Legen in „Eigenschaften Folgendes fest:
- Titel:
File Attachment Scanner Demo - Design Wählen Sie ein verfügbares Design aus (z. B. Arbeitsfläche).
Wählen Sie dann Erstellen aus.
- Titel:
-
Wählen Sie im Bestätigungsdialog die Option Öffnen aus, um das Formular im Editor zu öffnen.
Erwartetes Ergebnis: Der Editor für adaptive Formulare wird mit einem leeren Formular geöffnet.
-
Feld für Datei-Upload hinzufügen:
- Öffnen Sie den Komponenten-Browser (über das Symbol „Komponenten“ in der linken Leiste oder wählen Sie den leeren Formularbereich aus und wählen Sie die Option „Komponente einfügen„).
- Suchen Sie die Komponente Dateianhang und ziehen Sie sie auf das Formular.
-
Schaltfläche „Senden“ hinzufügen:
- Ziehen Sie im selben Komponenten-Browser eine Schaltfläche Adaptives Formular auf das Formular, und zwar unter dem Dateifeld.
- Wählen Sie die Schaltfläche aus, öffnen Sie ihre Eigenschaften (das Schraubenschlüsselsymbol), legen Sie ihren Schaltflächentyp auf Senden fest und bestätigen Sie den Vorgang.
-
Speichern Sie das Formular. Der Editor speichert automatisch, Sie können es jedoch erzwingen, indem Sie den Editor verlassen.
Erwartetes Ergebnis: Das Formular verfügt jetzt über ein Dateianhang-Feld und eine Senden-Schaltfläche.
Schritt 9: Verbinden des ClamAV-Scanners mit dem Formular step-9-connect
-
Wählen Sie im Formular-Editor den Guide-Container (der äußerste Container) aus, um die Eigenschaften Container für adaptive Formulare zu öffnen. Verwenden Sie das Symbol Eigenschaften (Schraubenschlüssel) .
-
Öffnen Sie die Registerkarte Übermittlung.
-
Suchen Sie die Dropdown Liste „File Attachment Virus Scanner / Validator und wählen Sie ClamAV Scanner.
Dieses Feld und die Liste der Optionen stammen aus Schritt 7: der Dialogfelderweiterung und dem Datenquellen-Servlet, die Sie in Ihrem eigenen Projekt bereitgestellt haben. Der Eintrag ist der Name, der von
getFileAttachmentValidatorName()in Ihrem Code zurückgegeben wird. Wenn SieVALIDATOR_NAMEgeändert haben, wählen Sie stattdessen diesen Namen aus.note important IMPORTANT Wenn dieses Feld vollständig fehlt, haben Sie Schritt 7 nicht abgeschlossen oder das ui.apps-Paket aus Schritt 7 wurde nicht bereitgestellt. Dieses Feld ist nie vorkonfiguriert für Formulare, die auf Kernkomponenten basieren. -
Wählen Sie Fertig und speichern Sie dann das Formular.
Schritt 10: Testen der Integration step-10-test
Testen Sie beide Ergebnisse.
Test A: Eine saubere Datei wird akzeptiert test-clean
-
Öffnen Sie die Vorschau des Formulars:
code language-none http://localhost:4502/content/dam/formsanddocuments/file-attachment-scanner-demo/jcr:content?wcmmode=disabledWenn sich der Pfad Ihres Formulars unterscheidet, öffnen Sie es in Forms und in Dokumenten und wählen Sie Vorschau.
-
Hängen Sie eine normale PDF oder ein normales Bild an und klicken Sie dann auf Senden.
Erwartetes Ergebnis: Das Formular wurde erfolgreich gesendet.
Test B: Ein Testvirus ist blockiert test-virus
-
Erstellen Sie eine Nur-Text-Datei mit dem Namen
eicar.txt, deren Inhalt nur die standardmäßige EICAR-Antiviren-Testzeichenfolge ist. Dies ist eine harmlose Datei, die jede Antiviren-Engine absichtlich erkennt:code language-none X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*Sie können es auch von eicar.org herunterladen.
-
Fügen Sie im Formular
eicar.txtan und wählen Sie Senden.Erwartetes Ergebnis: Die Übermittlung ist blockiert. Wie die Zurückweisung angezeigt wird, hängt von der konfigurierten Übermittlungsaktion ab: Ein standardmäßiger Dankeseiten-Seitenfluss zeigt in der Regel einen Inline-Fehler im Dateifeld an, während An REST-Endpunkt übermitteln (im Beispielformular dieses Tutorials wird dies verwendet) in der Regel eine generische Meldung anzeigt, bei der die Übermittlung fehlgeschlagen ist, anstatt einer Meldung auf Feldebene. In beiden Fällen wird das Formular nicht übermittelt.
-
Bestätigen Sie, dass der Validator tatsächlich ausgeführt und die Datei abgelehnt hat. Überprüfen Sie das AEM-Fehlerprotokoll. Dies ist die zuverlässige Methode, um zu sehen, was passiert ist, unabhängig davon, wie der Fehler im Browser angezeigt wurde:
code language-none <AEM_SDK_FOLDER>/crx-quickstart/logs/error.logSuchen Sie nach der Ablehnungsmeldung von Ihrem Validator (z. B.
A virus was detected in the attached file).
Fehlerbehebung troubleshooting
docker runschlägt mit no matching manifest for linux/arm64/v8 fehl. Sie befinden sich auf einem Apple Silicon Mac; das clamav/clamav-Image hat keinen nativen arm64-Build. Fügen Sie dem Befehl in Schritt 1 --platform linux/amd64 hinzu.
PONGin Schritt 1 nicht zurückgegeben. clamd ist nicht bereit oder der Port ist nicht veröffentlicht. Überprüfen Sie docker logs clamav auf den Abschluss des Datenbank-Ladevorgangs und bestätigen Sie, dass der Container dem Port 3310 (docker ps) zugeordnet ist.
Der Archetyp-Befehl von Schritt 2 schlägt mit Unsupported class file major version... fehl. Ihr standardmäßiges java/mvn wird auf einem neueren JDK ausgeführt als #5 Annahme zulässt: Das Post-Generation-Skript des Archetyps kann Klassendateien aus Java-Versionen neuer als 21 nicht analysieren. Verweisen Sie JAVA_HOME auf eine Java 11- oder Java 21-Installation und führen Sie den Befehl erneut aus. Wenn beim ersten Versuch bereits teilweise ein Projekt generiert wurde (nicht übereinstimmende Modulordner, fehlende Dateien), löschen Sie dieses Ausgabeverzeichnis, bevor Sie es erneut versuchen, anstatt es an Ort und Stelle erneut auszuführen.
Projekt wird nicht kompiliert (FileAttachmentValidator kann nicht gefunden werden). Die Early-Access-Abhängigkeit (Schritt 3) fehlt, wurde nicht in Ihrem lokalen Maven-Repository installiert oder die Version von pom.xml stimmt nicht mit der installierten JAR-Datei überein. Überprüfen Sie die Version mit unzip -l addon.far | grep adobe-xfaforms-common erneut.
Komponente ist in Schritt 5 nicht erfüllt. Öffnen Sie http://localhost:4502/system/console/components, suchen Sie ClamAVFileAttachmentValidator und lesen Sie den Grund. Eine fehlende Schnittstelle bedeutet normalerweise, dass die Abhängigkeit zur Laufzeit nicht vorhanden ist. Vergewissern Sie sich, dass Ihre AEM-Umgebung über die Early-Access-Funktion verfügt.
Das Feld Virenscanner/Validator für Dateianhänge wird auf der Registerkarte Übermittlung überhaupt nicht angezeigt (Schritt 9). Bestätigen Sie, dass das Paket Schritt 7 ui.apps (die Dialogfelderweiterung und das Datenquellen-Servlet) tatsächlich bereitgestellt wurde. Überprüfen Sie http://localhost:4502/system/console/components auf FileAttachmentValidatorDataSourceServlet. Bestätigen Sie außerdem, dass der Umschalter FT_FORMS-23497-Funktion für Ihr Programm aktiviert ist. Dadurch wird die zugrunde liegende FileAttachmentValidatorManager-Funktion geprüft, von der die Datenquelle abhängt.
Das Feld wird angezeigt, aber ClamAV Scanner ist nicht in der Dropdown-Liste (Schritt 9). Vergewissern Sie sich, dass die ClamAVFileAttachmentValidator aktiv ist, dass getFileAttachmentValidatorName() einen eindeutigen, nicht leeren Wert zurückgibt, und laden Sie den Formular-Editor nach der Bereitstellung neu.
Jede Datei wird abgelehnt, auch saubere. Der Validator kann nicht geschlossen werden, was in der Regel bedeutet, dass er clamd nicht erreichen kann. Überprüfen Sie Schritt 1 erneut (läuft clamd und kehrt PONG zurück?) und Schritt 6 (Host, Port, Zeitüberschreitung). Suchen Sie in error.log nach Verbindungsfehlern oder ERROR.
Scannt Zeitüberschreitung oder INSTREAM size limit exceeded. Die Datei ist zu groß für die Zeitüberschreitung oder die StreamMaxLength von clamd. Erhöhen Sie die maximale Wartezeit in Schritt 6, erhöhen Sie die StreamMaxLength in clamd.conf und legen Sie eine maximale Dateigröße für die Komponente Dateianhang fest, damit übergroße Dateien früher gestoppt werden.
Bei der EICAR-Übermittlung wird eine allgemeine Fehlermeldung und keine Inline-Feldmeldung angezeigt (Schritt 10). Dies ist bei einer Übermittlungsaktion An REST-Endpunkt übermitteln zu erwarten; es ändert nichts daran, ob die Datei tatsächlich abgelehnt wurde. Überprüfen Sie error.log zur Bestätigung der Zurückweisungsmeldung des Validators.
Häufig gestellte Fragen faq
Kann AEM Forms Uploads mit ClamAV scannen?
Ja. Sie implementieren die FileAttachmentValidator mit einem Service, der jede hochgeladene Datei bei der Übermittlung an einen ClamAV-Daemon (clamd) streamt und die Datei ablehnt, wenn ClamAV eine Bedrohung meldet.
Muss ich ClamAV auf dem AEM-Server installieren?
Anzahl clamd wird als separater Prozess ausgeführt. Ihr Validator stellt eine Verbindung dazu über TCP her. Führen Sie sie lokal für die Entwicklung und als gemeinsamen oder externen Service in realen Umgebungen aus.
Welchen Port verwendet Clamd?
Standardmäßig ist TCP-Port 3310. Der Beispiel-Validator verwendet diesen Port und lässt Sie über die OSGi-Konfiguration ändern.
Wie kann ich testen, ob die Virensuche funktioniert?
Übermitteln Sie eine gewöhnliche Datei, um zu bestätigen, dass sie akzeptiert wird, und übermitteln Sie dann die EICAR-Testdatei (eine harmlose, dem Industriestandard entsprechende Testzeichenfolge), um zu bestätigen, dass sie erkannt und blockiert wird.
Warum werden alle meine Dateien abgelehnt?
Der Beispielvalidator schlägt fehl und führt aufgrund eines Verbindungsproblems mit clamd dazu, dass jede Datei abgelehnt wird. Überprüfen Sie, ob clamd ausgeführt und erreichbar ist, und überprüfen Sie die Host-, Port- und Zeitüberschreitungseinstellungen.
Kann ich ClamAV mit AEM as a Cloud Service verwenden?
Ja, aber Sie können clamd nicht auf dem AEM-Host ausführen. Führen Sie es als gemeinsam verwendeten oder externen Service aus und lassen Sie den Validator darauf verweisen, idealerweise in derselben Region, um Dateiinhalte in Ihrer Umgebung zu speichern.
Kann ich die Prüfung vor der Übermittlung ausführen, sobald die Datei angehängt ist?
Ja. Der Validator dieses Tutorials wird bei der Übermittlung ausgeführt. Um zu überprüfen, sobald ein Benutzer eine Datei angehängt hat, bevor er sie sendet, verwenden Sie den Vorgang Service aufrufen im Regeleditor für adaptive Forms, um einen Scan-Service für das Änderungsereignis des Dateifelds aufzurufen. Siehe Aufrufen von Service-Verbesserungen im Regeleditor.