Utvidet filvalidering
Hvordan utføre utvidet filvalidering?
Innledning
Som standard utføres bare enkel validering av en fil før den lastes opp og lagres. Dette for å sikre at filen overholder reglene satt for datatypen og/eller opplastingskomponenten. Disse sjekkene inkluderer:
- Er filutvidelsen gyldig i henhold til de konfigurerte MIME-typene?
- Filstørrelsen er under den konfigurerte grensen.
- Antall opplastede filer er under den konfigurerte grensen.
Utvidet filvalidering legger til mulighet for å analysere byte-strømmen til de opplastede filene før de lagres, og returnere feilmeldinger til klienten hvis det er noe galt. Som standard inkluderes en MIME-typekontroller som skanner filen for å se om den er av den typen den hevder å være. Man kan lage og legge til egenutviklede valideringer for å validere ulike typer filer og metadata. Du kan for eksempel skrive en analyse som sjekker om en PNG-fil har en minimumsoppløsning før den godtas, eller om en PDF-fil er av en bestemt versjon.
Altinn.App.Core NuGet-pakken definerer grensesnittene som kreves i tillegg til å sikre at koden kalles. Analyseimplementeringene opprettes som en separat NuGet-pakke som kan importeres i applikasjonen din. Dette gjøres for å holde kjernen til en Altinn 3-applikasjon så liten som mulig, og for å kunne lansere og bruke nye analyser uten å måtte oppgradere applikasjonen (utover v7.10.0).
Hvordan konfigurere og aktivere standard MIME-type validering i applikasjonen din
- Legg til en referanse til Altinn.FileAnalyzers NuGet-pakken
Åpne kommandolinjen til applikasjonsrepoet og naviger til mappen App der App.csproj-filen er plassert, og kjør følgende kommando:nuget install Altinn.FileAnalyzers
- Registrer tjenesten for MIME-type valideringen slik at de blir tilgjenglelig
services.AddMimeTypeValidation();
- Konfigurer validatoren for den datatypen den skal brukes for
Validatoren konfigureres per datatypen og vil bare kjøre mot den konfigurerte datatypen. Eksemplet nedenfor konfigurerer MIME-type analysen og den tilhørende valideringskomponenten.{ "id": "08112113-cc3a-4d35-a8d2-bfba53a1ddfd", "allowedContentTypes": ["image/jpeg", "application/pdf"], "taskId": "Task_1", "maxSize": 25, "maxCount": 1, "minCount": 1, "enablePdfCreation": false, "enabledFileAnalysers": [ "mimeTypeAnalyser" ], "enabledFileValidators": [ "mimeTypeValidator" ] }
- Legg til støtte for JSON-objekter i dataresponsen
Dette forteller frontend å se etter JSON i svaret for å gi en feilmelding til brukeren."FeatureManagement": { "JsonObjectInDataResponse": true }
Hvordan skrive din egen analyse
Hvis du vil skrive din egen validator, må du implementere to interface: IFileAnalyser
og IFileValidator
. IFileAnalyser
analyserer filen for eventuelle metadata du vil validere på og returnerer disse i en FileAnalysisResult
. Resultatet sendes deretter til valideringslogikken. Resultatet inneholder noen navngitte egenskaper som filnavn, MIME-type og ID-en til analysatoren som ble brukt for å opprette resultatet. Eventuelle tilleggsmetadata sendes som nøkkel/verdi-par i Metadata propertyen. Denne separasjonen er primært gjort for å tillate gjenbruk av analysatoren for å ekstrahere metadata om filen for andre formål.
- Implementer grensesnittet
IFileAnalyser
Grensesnittet har en egenskapId
og en metodeAnalyse
som må implementeres.Id
-egenskapen skal være unik og brukes når du konfigurerer analysatoren i filenapplicationmetadata.json
. Dette er hvordan implementasjonen din blir valgt når applikasjonen bestemmer hvilken analyse som skal kjøres for en gitt datatype.
Eksempel fra standardimplementeringen av MIME-type-analysatoren:Metodenpublic string Id { get; private set; } = "mimeTypeAnalyser";
Analyse
får bytestrømmen som representerer filen og et filnavn hvis tilgjengelig (vanligvis er det tilgjengelig). Strømmen er allerede satt til posisjon 0 og kan leses direkte.
Eksempel fra standardimplementeringen av MIME-type-analysatoren:public async Task<FileAnalysisResult> Analyse(Stream stream, string? filename = null) { var results = _inspector.Inspect(stream); var match = results.OrderByDescending(match => match.Points).FirstOrDefault(match => match.Percentage == 1); // Du oppgir ID-en til analysatoren i resultatet for å kunne skille mellom resultater fra forskjellige analysatorer. var fileAnalysisResult = new FileAnalysisResult(Id); if (match != null) { fileAnalysisResult.Extensions = match.Definition.File.Extensions.ToList(); fileAnalysisResult.MimeType = match.Definition.File.MimeType; fileAnalysisResult.Filename = filename; fileAnalysisResult.Metadata.Add("key", "value"); //Dette viser bare hvordan du legger til egendefinerte metadata. } return fileAnalysisResult; }
- Implementer grensesnittet
IFileValidator
Basert på analyseresultatet kan du skrive valideringslogikken. Valideringen vil være tett knyttet til metadataegenskapene du vil validere mot, noe som betyr at du må vite nøkkelen og typen verdier som forventes.
Grensesnittet har en egenskapId
og en metodeValidate
som må implementeres.Id
-egenskapen skal være unik og brukes når du konfigurerer analysatoren i filenapplicationmetadata.json
. Dette er hvordan implementasjonen din blir valgt når applikasjonen bestemmer hvilken validering som skal kjøres for en gitt datatype.
Eksempel fra standardimplementeringen av MIME-type validatoren:Metodenpublic string Id { get; private set; } = "mimeTypeValidator";
Validate
får datatypen den kjører for, og resultatet fra analysen. Den returnerer enbool
som indikerer om valideringen var vellykket eller ikke, og i tilfelle feil blir det returnert en liste over feil.public async Task<(bool Success, IEnumerable<ValidationIssue> Errors)> Validate(DataType dataType, IEnumerable<FileAnalysisResult> fileAnalysisResults) { List<ValidationIssue> errors = new(); var fileMimeTypeResult = fileAnalysisResults.FirstOrDefault(x => x.MimeType != null); // Sjekk om filens MIME-type er en tillatt innholdstype if (!dataType.AllowedContentTypes.Contains(fileMimeTypeResult?.MimeType, StringComparer.InvariantCultureIgnoreCase) && !dataType.AllowedContentTypes.Contains("application/octet-stream")) { ValidationIssue error = new() { Source = "File", Code = ValidationIssueCodes.DataElementCodes.ContentTypeNotAllowed, Severity = ValidationIssueSeverity.Error, Description = $"Filen {fileMimeTypeResult?.Filename + " "}virker ikke å være av en tillatt innholdstype i henhold til konfigurasjonen for datatypen {dataType.Id}. Tillatte innholdstyper er {string.Join(", ", dataType.AllowedContentTypes)}", CustomTextKey = "My.text.resource.key" }; errors.Add(error); return (false, errors); } return (true, errors); }
- Registrer implementasjonen i applikasjonens DI-kontainer
Når koden din er på plass, må du registrere implementasjonen for at koden skal bli utført når filer lastes opp.services.AddTransient<IFileAnalyser, YourAnalyserImplementation>(); services.AddTransient<IFileValidator, YourValidatorImplementation>();
- Konfigurer analysen og validatoren
Når du har implementert analysatoren og valideringslogikken, må du konfigurere de i filen applicationmetadata.json. I konfigurasjonen av datatypen må du legge til analysatoren og valideringskomponenten med riktig ID.
{ "id": "08112113-cc3a-4d35-a8d2-bfba53a1ddfd", "allowedContentTypes": [ "image/jpeg", "application/pdf" ], "taskId": "Task_1", "maxSize": 25, "maxCount": 1, "minCount": 1, "enablePdfCreation": false, "enabledFileAnalysers": [ "mimeTypeAnalyser" ], "enabledFileValidators": [ "mimeTypeValidator" ] }