教學課程:使用防毒軟體掃描檔案附件
[AEM Forms]{class="badge positive" title="套用至AEM Forms"}
檔案附件病毒掃描程式/驗證程式功能屬於早期採用者程式。 您可以使用官方電子郵件 ID 寫信至 aem-forms-ea@adobe.com,以加入早期採用者計劃並要求存取該功能。
本教學課程將帶您進行端對端教學。 您將執行ClamAV防毒引擎、將自訂驗證器新增至AEM、使用檔案上傳欄位建立範例調適型表單、連線驗證器,並確認在提交時已拒絕感染病毒的檔案。 即使您是AEM的新手,也會寫入以供遵循。 您需要的每個命令、熒幕路徑和值都會標示出來。
如需驗證器和介面參考背後的概念,請參閱隨附文章使用自訂驗證器在Adaptive Forms中掃描檔案附件。 您不需要先閱讀本教學課程就能完成本教學課程,但本教學課程會說明為何每篇文章都存在。
您將要建置的內容 what-you-will-build
到最後,您將擁有:
- 執行中的ClamAV常駐程式(
clamd),可依要求掃描檔案。 - 自訂AEM服務(ClamAV掃描程式),可將每個上傳的檔案傳送至
clamd並拒絕受感染的檔案。 - 名為 File Attachment Scanner Demo 的最適化表單範例,包含檔案上傳欄位和提交按鈕。
- 有效測試:成功提交普通檔案,且封鎖已知的測試病毒檔案。
開始之前:假設和先決條件 assumptions
本教學課程假設使用下列設定。 如果遺失任何專案,請在啟動前安裝或取得該專案。 每個專案都包含檢查方式。
http://localhost:4502連線http://localhost:4502。 您應該會看到AEM登入或開始畫面。http://localhost:4502 (預設的本機認證為admin / admin)FT_FORMS-23497FileAttachmentValidatorManager功能。 提交索引標籤欄位本身就是本教學課程在步驟7中新增的內容。 兩者皆不存在現成可用的。ui.apps模組中建立最適化表單容器Proxy元件java -versionmvn -versiondocker --versioncom.adobe.forms.common.service介面的Early Access相依性aem-forms-addon-sdk-<version>.zip (需要早期採用者程式權益)您將取代的值 substitute-values
無論您在何處看到這些預留位置,都請將其取代為您自己的值:
<PROJECT_ROOT>:您AEM Maven專案的資料夾。<APP_ID>:您的專案的應用程式識別碼或套件組合模組名稱(例如,mysite)。<SDK_DEPENDENCY_VERSION>:您下載的SDK中隨附的adobe-xfaforms-common版本(群組ID和成品ID已修正;請參閱步驟3)。
藍圖 roadmap
您可以依序完成這些步驟:
- 啟動ClamAV常駐程式(
clamd)。 - 設定AEM Maven專案(如果您已經有專案,請略過)。
- 新增早期存取相依性。
- 新增ClamAV驗證器類別。
- 建置並部署至AEM。
- 在AEM中設定
clamd連線。 - 將驗證器欄位新增至表單對話方塊。
- 建立範例最適化表單。
- 將ClamAV掃描器連線至表單。
- 使用乾淨的檔案和測試病毒檔案進行測試。
步驟1:啟動ClamAV精靈 step-1-clamd
ClamAV是以名為clamd的背景服務執行。 您建置的驗證器會將每個上傳的檔案串流至clamd,後者會回覆OK以取得乾淨的檔案,或在偵測到威脅名稱時報告威脅名稱。
執行clamd最快的方法是Docker。
-
啟動ClamAV:
code language-none docker run -d --name clamav -p 3310:3310 clamav/clamav:latestnote NOTE 在Apple Silicon (arm64) Mac上,此影像沒有原生arm64組建,且上述命令因 no matching manifest for linux/arm64/v8而失敗。 新增--platform linux/amd64以改為在模擬下執行:code language-none docker run -d --name clamav --platform linux/amd64 -p 3310:3310 clamav/clamav:latest -
等待它準備就緒。 第一次啟動時,它會下載病毒資料庫,這可能需要幾分鐘的時間。 在資料庫載入且
clamd正在接聽之前,請注意記錄檔:code language-none docker logs -f clamav按
Ctrl+C在記錄準備就緒後停止追蹤記錄。 -
驗證是否可在連線埠
3310上連線clamd:code language-none printf 'PING\n' | nc localhost 3310預期結果:回應為
PONG。
clamd.conf中的連線埠3310上啟用clamd精靈和TCP通訊端,使用freshclam更新資料庫,然後啟動clamd。 然後執行上述步驟3中的驗證。clamd以自己的程式執行,與AEM分開。 此本機設定供開發使用。 在AEM as a Cloud Service上,您無法在AEM主機上執行clamd,因此在實際環境中,您是以共用位置或外部服務的形式執行,並指向驗證器。 您偏好在同一區域共用執行個體,以將檔案內容儲存在您的環境中,以利資料常駐和法規遵循。步驟2:設定AEM Maven專案 step-2-project
自訂Java程式碼會作為由Maven專案建置的套件部署到AEM。 如果您已有AEM專案,請跳至步驟3並使用其套件組合模組(通常名為core)。
如果您沒有這類專案,請使用AEM專案原型建立專案:
-
在終端機中,前往您保留程式碼並執行原型的資料夾。 以小寫名稱取代
<APP_ID>,例如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=cloud預期結果:包含包含
core、ui.apps和all等模組的新資料夾<APP_ID>(這是您的<PROJECT_ROOT>)。 -
您稍後新增的Java程式碼會進入
core模組中的:code language-none <PROJECT_ROOT>/core/src/main/java/
core模組。步驟3:新增搶先存取相依性 step-3-dependency
您的程式碼會針對來自com.adobe.forms.foundation:adobe-xfaforms-common的FileAttachmentValidator介面進行編譯(假設#9)。 此相依性未發佈到公共Maven存放庫。 它隨附在AEM Forms附加元件SDK中,因此您可以從其中擷取並安裝到本機Maven存放庫中。
-
從Adobe軟體發佈入口網站下載
aem-forms-addon-sdk-<version>.zip的最新可用組建 (需要早期採用者程式權益)。 請一律使用最新組建版本;舊版組建版本可能尚未包含此相依性。 -
擷取相依性jar。 SDK zip包含功能封存(
.far),而jar是內建於其中: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-common第二個命令會顯示下載中套件的jar路徑和版本,例如
com/adobe/forms/foundation/adobe-xfaforms-common/<version>/adobe-xfaforms-common-<version>.jar。 在下一個步驟中使用該路徑和版本。code language-none unzip -p addon.far "com/adobe/forms/foundation/adobe-xfaforms-common/<version>/adobe-xfaforms-common-<version>.jar" > adobe-xfaforms-common.jar -
將解壓縮的jar安裝到您的本機Maven存放庫中,以便
pom.xml可以解析它。 包含-DgeneratePom=true: jar會將自己的內部Adobe組建POM嵌入您專案無法解析的父系參考,而且此標幟會將其取代為乾淨的自含式標幟: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 -
開啟
<PROJECT_ROOT>/core/pom.xml。 -
在
<dependencies>區段內,使用您剛安裝的相同版本新增相依性。 使用provided範圍,因為介面是由AEM在執行階段提供:code language-xml <dependency> <groupId>com.adobe.forms.foundation</groupId> <artifactId>adobe-xfaforms-common</artifactId> <version><SDK_DEPENDENCY_VERSION></version> <scope>provided</scope> </dependency> -
儲存檔案。
步驟4:新增ClamAV驗證器類別 step-4-class
-
在下列位置建立新檔案:
code language-none <PROJECT_ROOT>/core/src/main/java/com/example/forms/security/ClamAVFileAttachmentValidator.java建立
forms/security資料夾(如果沒有)。 您可以使用自己的封裝名稱。 如果是,請變更package行以符合。 -
貼上下列程式碼:
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; } } -
儲存檔案。
步驟5:建置並部署至AEM step-5-deploy
-
在AEM執行中(假設#1),從您的專案根目錄中建置和部署。 此命令會將套件安裝到本機編寫執行個體:
code language-none cd <PROJECT_ROOT> mvn clean install -PautoInstallBundle預期結果:組建結束於
BUILD SUCCESS。 -
確認服務執行中。 開啟元件主控台:
code language-none http://localhost:4502/system/console/components此頁面沒有內建搜尋方塊:列出5,000個以上的元件,請使用瀏覽器自己的頁面尋找功能(Cmd+F或Ctrl+F)並搜尋
ClamAVFileAttachmentValidator。預期結果:元件已列出,其狀態為使用中 (或已滿足)。 如果不滿意,請參閱疑難排解。
步驟6:設定夾式連線 step-6-config
告知驗證器clamd的位置。 對於本機開發,預設值(localhost:3310)已經與步驟1相符,因此只有在您的值不同時才需要此步驟。 執行一次以確認設定存在。
-
開啟設定主控台:
code language-none http://localhost:4502/system/console/configMgr -
此頁面也沒有內建搜尋方塊:請使用瀏覽器的頁面內尋找(Cmd+F或Ctrl+F)來尋找 ClamAV檔案附件掃描器 並開啟它。
-
確認或設定:
table 0-row-2 1-row-2 2-row-2 3-row-2 設定 本教學課程的值 夾式主機 localhost固定連線埠 3310掃描逾時(毫秒) 30000OSGi設定主控台中的
-
選取「儲存」。
.cfg.json檔案),以便它們隨著每個部署移動,而不是手動設定。步驟7:將驗證器欄位新增至表單對話方塊 step-7-dialog-field
檔案附件病毒掃描程式/驗證器欄位不在現成的最適化表單容器對話方塊中。 對於以核心元件為基礎的表單,您可在自己的專案中新增一次。 此為一次性步驟;若稍後新增更多驗證器,請勿重複此步驟。
-
如果您的
formcontainerProxy元件尚不存在,請於下列位置建立它: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"/>如果您已有此元件(大部分從核心元件原型建立的專案都有),請跳至下一個步驟。
-
在下列位置建立對話方塊擴充功能:
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>這僅會定義一個新欄位,映象真實對話方塊的節點名稱直到插入點。 它不會重新定義或取代任何現有的提交索引標籤欄位。 請參閱將驗證器欄位新增至隨附文章中的表單對話方塊,瞭解其運作原因。
-
新增列出已註冊驗證器的資料來源servlet。 無論您使用哪個驗證器引擎,它都是相同的;請參閱將驗證器欄位新增至表單對話方塊 (在隨附文章中),以瞭解它的功用及原因。 建立時間:
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)); } }將對話方塊XML和Servlet的
resourceTypes中的<APP_ID>取代為您專案的實際應用程式ID (符合假設#4),如果您的套件名稱與步驟4不同,請調整套件名稱。 -
建置和部署這兩個變更。 您已變更內容(對話方塊)和程式碼(servlet),因此請同時使用這兩個設定檔:
autoInstallPackage僅會部署內容,並保留servlet的套件組合未重新部署。code language-none cd <PROJECT_ROOT> mvn clean install -PautoInstallPackage,autoInstallBundle預期結果:組建結束於
BUILD SUCCESS,且ui.apps內容封裝(包括此對話方塊變更)和core套件(包括新的servlet)都已安裝。
FileAttachmentValidator都會自動顯示在下拉式清單中,因為每個都有自己的getFileAttachmentValidatorName(),而emptyText="None"會保留「無驗證器」作為預設值,因此現有表單在您明確選擇其中一個表單之前不受影響。步驟8:建立範例最適化表單 step-8-form
現在使用file-upload欄位建立簡單表單。
-
開啟Forms和檔案:
code language-none http://localhost:4502/aem/forms.html/content/dam/formsanddocuments -
選取建立 (右上方),然後選取最適化表單。
-
從相簿選取範本。 基礎不是個別的問題:它是您挑選的範本的一部分,以小字幕顯示在每個範本的名稱下(例如,最適化表單(核心元件))。
note important IMPORTANT 數個範本全名為空白表單:一個用於核心元件,一個用於基礎元件,一個用於Edge Delivery Services。 選錯的容易漏選,且不會發生錯誤:本教學課程的其餘部分似乎仍可運作,但系統從未叫用檔案附件病毒掃描器/驗證器欄位,因為該管道僅存在於核心元件型表單中。 在繼續之前,請確認副標題是否顯示最適化表單(核心元件)。 -
在 屬性 中,設定:
- 標題:
File Attachment Scanner Demo - 佈景主題:挑選任何可用的佈景主題(例如畫布)
然後選取建立。
- 標題:
-
在確認對話方塊中,選取 開啟 以在編輯器中開啟表單。
預期結果:最適化表單編輯器以空白表單開啟。
-
新增檔案上傳欄位:
- 開啟 元件 瀏覽器(左側邊欄中的元件圖示,或選取空白表單區域並選擇「插入元件」選項)。
- 尋找 檔案附件 元件,並將其拖曳至表單上。
-
新增提交按鈕:
- 從相同的「元件」瀏覽器,將 最適化表單按鈕 拖曳至表單上檔案欄位下方。
- 選取按鈕、開啟其屬性(扳手圖示)、將其 按鈕型別 設定為提交,然後確認。
-
儲存表單。 編輯器會自動儲存,但您可以離開編輯器以強制儲存。
預期結果:表單現在有檔案附件欄位和提交按鈕。
步驟9:將ClamAV掃描器連線至表單 step-9-connect
-
在表單編輯器中,選取參考線容器 (最外層的容器)以開啟 最適化表單容器 屬性。 使用「屬性」(扳手)圖示。
-
開啟 提交 標籤。
-
找到 檔案附件病毒掃描程式/驗證器 下拉式清單,然後選取ClamAV掃描程式。
此欄位及其選項清單來自步驟7:對話方塊擴充功能和資料來源servlet ,您已部署至自己的專案。 此專案是程式碼中
getFileAttachmentValidatorName()傳回的名稱。 如果您變更了VALIDATOR_NAME,請改為選取該名稱。note important IMPORTANT 如果此欄位完全遺失,表示您尚未完成步驟7,或步驟7中的 ui.apps封裝未部署。 此欄位絕不會開箱即用於核心元件型表單。 -
選取完成,然後儲存表單。
在[檔案附件病毒掃描程式/驗證器]欄位中選取ClamAV掃描程式的[最適化表單容器]對話方塊的
步驟10:測試整合 step-10-test
測試兩個結果。
測試A:接受乾淨的檔案 test-clean
-
開啟表單的預覽:
code language-none http://localhost:4502/content/dam/formsanddocuments/file-attachment-scanner-demo/jcr:content?wcmmode=disabled如果表單的路徑不同,請從Forms & Documents開啟它,並選取預覽。
-
附加一般PDF或影像,然後選取提交。
預期結果:表單已成功提交。
測試B:已封鎖測試病毒 test-virus
-
建立名為
eicar.txt的純文字檔,其唯一內容是標準EICAR防毒測試字串。 這是每個防毒引擎都會主動偵測的無害檔案:code language-none X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*您也可以從eicar.org下載。
-
在表單中附加
eicar.txt並選取提交。預期結果:提交已封鎖。 拒絕的呈現方式因表單設定的 提交動作 而異:標準的感謝頁面流程通常會在檔案欄位上顯示內嵌錯誤,而提交至REST端點 (此教學課程的範例表單使用此功能)傾向於顯示一般提交失敗的訊息,而非欄位層級的訊息。 無論如何,表單都不會提交。
-
確認驗證器已實際執行並拒絕檔案。 檢查AEM錯誤記錄,這是檢視所發生事件的可靠方式,無論失敗以何種方式顯示在瀏覽器中:
code language-none <AEM_SDK_FOLDER>/crx-quickstart/logs/error.log尋找來自驗證程式的拒絕訊息(例如,
A virus was detected in the attached file)。
疑難排解 troubleshooting
docker run失敗,錯誤為no matching manifest for linux/arm64/v8. 您使用的是Apple Silicon Mac;clamav/clamav影像沒有原生arm64組建。 將--platform linux/amd64新增至步驟1中的命令。
步驟1中未傳回PONG。 clamd未就緒或連線埠未發佈。 檢查docker logs clamav的資料庫載入完成,並確認容器對應連線埠3310 (docker ps)。
步驟2的原型命令因Unsupported class file major version...而失敗。 您的預設java/mvn正在較新的JDK上執行,而非#5允許的假設:原型的產生後指令碼無法從較21新的Java版本剖析類別檔案。 將JAVA_HOME指向Java 11或21安裝,然後重新執行命令。 如果第一次嘗試已部分產生專案(模組資料夾不符、遺漏檔案),請在重試之前刪除該輸出目錄,而不是就地重新執行。
專案未編譯(找不到FileAttachmentValidator)。 早期存取相依性(步驟3)遺失、未安裝至您的本機Maven存放庫,或pom.xml的版本不符合您安裝的jar。 透過unzip -l addon.far | grep adobe-xfaforms-common重新檢查版本。
元件在步驟5.中未滿足 開啟http://localhost:4502/system/console/components、尋找ClamAVFileAttachmentValidator並閱讀原因。 缺少介面通常表示執行階段不存在相依性。 確認您的AEM環境具有搶先存取功能。
檔案附件病毒掃描程式/驗證程式欄位完全沒有出現在提交索引標籤上(步驟9)。 確認步驟7 ui.apps套件(對話方塊擴充功能和資料來源servlet)已實際部署。 檢查FileAttachmentValidatorDataSourceServlet的http://localhost:4502/system/console/components。 同時確認已為您的程式啟用FT_FORMS-23497功能切換;它會啟動資料來源所依賴的基礎FileAttachmentValidatorManager功能。
欄位已顯示,但ClamAV掃描器不在下拉式清單中(步驟9)。 確認ClamAVFileAttachmentValidator元件作用中,getFileAttachmentValidatorName()傳回唯一的非空白值,並在部署後重新載入表單編輯器。
每個檔案都遭到拒絕,即使是乾淨的檔案也是如此。 驗證器無法關閉,因此這通常表示它無法達到clamd。 重新檢查步驟1 (clamd是否正在執行並傳回PONG?) 和步驟6 (主機、連線埠、逾時)。 檢視error.log中的連線錯誤或ERROR回應。
掃描逾時或INSTREAM size limit exceeded. 檔案太大,逾時或clamd的StreamMaxLength無法存取。 在步驟6中增加逾時,在clamd.conf中引發StreamMaxLength,並在檔案附件元件上設定檔案大小上限,如此一來,過大的檔案會提早停止。
EICAR提交會顯示一般錯誤,而非內嵌欄位訊息(步驟10)。 這是 提交至REST端點 提交動作的預期結果;它不會變更檔案是否實際遭拒。 檢查error.log以確認驗證程式的拒絕訊息。
常見問題 faq
AEM Forms是否可以使用ClamAV掃描上傳?
是。您實作FileAttachmentValidator介面的服務會在提交時將每個上傳的檔案串流至ClamAV精靈(clamd),並在ClamAV回報威脅時拒絕檔案。
我需要在AEM伺服器上安裝ClamAV嗎?
第clamd個以個別處理程式執行。您的驗證器會透過TCP連線到它。在本機執行以進行開發,並在實際環境中以共用位置或外部服務的形式執行。
夾住使用哪個連線埠?
依預設,TCP連線埠3310。範例驗證器會使用此連線埠,並讓您透過OSGi設定加以變更。
如何測試病毒掃描的運作方式?
提交普通檔案以確認其被接受,然後提交EICAR測試檔案(無害的產業標準測試字串)以確認其被偵測到並遭到封鎖。
為什麼我的所有檔案都被拒絕?
範例驗證器無法關閉,因此clamd的連線問題會導致每個檔案都遭到拒絕。確認clamd正在執行且可連線,並檢查主機、連線埠和逾時設定。
我可以搭配AEM as a Cloud Service使用ClamAV嗎?
是,但您無法在AEM主機上執行clamd。請將它當成並存服務或外部服務來執行,並將驗證器指向它,最好是在相同的區域,以將檔案內容儲存在您的環境中。
我可以在附加檔案後,立即執行早於提交的檢查嗎?
是。本教學課程的驗證器會在提交時執行。若要在使用者附加檔案後立即進行驗證,在提交之前,請使用Adaptive Forms規則編輯器中的 叫用服務 操作,在檔案欄位的變更事件上呼叫掃描服務。請參閱規則編輯器中的啟動服務增強功能。