2017-04-07 3 views
0

Ich habe einen einfachen Web-API-2-Controller, der Datei-Uploads verarbeitet. Es sieht wie folgt aus:Authentifizieren der Web-API-Sitzung vor dem Body-Upload

[MyCustomAuthenticationFilter] 
[Authorize] 
public class FileController : ApiController 
{ 
    private IFileRepository _FileRepository; 

    public FileController(IFileRepository fileRepository) 
    { 
     _FileRepository = fileRepository; 
    } 

    public async Task<FileInfo> Post() 
    { 
     var stream = await Request.Content.ReadAsStreamAsync();    
     var info = await _FileRepository.CreateFileAsync(stream); 

     return new FileInfo(info); 
    } 
} 

Es dauert eine gestreamte Upload vom Client, reicht es zu einem Repository-Objekt aus (die zu einem Azure Storage Blob Container spricht), und gibt dann einige Daten über die hochgeladenen Datei. Einfach genug, und es funktioniert großartig.

Der Authentifizierungsfilter wird erst angewendet, wenn der Client das Hochladen der Datei abgeschlossen hat. Die Authentifizierung ist ein einfaches Challenge/Response-System, das ein Token verwendet. Dies bedeutet, dass ein Client problemlos mehrere hundert Megabyte Daten hochladen kann (möglicherweise über eine langsame Mobilfunkverbindung), bevor er feststellt, dass sein Token abgelaufen ist nochmal. Ich würde gerne in der Lage sein, den Anfrage-Header zu prüfen und ihn so früh wie möglich zu validieren (oder abzulehnen), aber das scheint mit den Standardfiltern nicht machbar zu sein. Ich habe auch versucht, eine einfache IHttpModule und Hooking in die BeginRequest Ereignis, aber das offenbar nicht feuern, bis nach dem Upload, entweder.

Wie kann ich mich in die Pipeline einklinken, sodass ich die Autorisierungsheader für eine Anfrage validieren kann, bevor der Client hochgeladen wird?

bearbeiten hinzuzufügen: Offensichtlich früh hat Authentifizieren mir nichts nützen, wenn ich nicht auch, basierend auf der Strecke in Web API autorisieren kann. Mein Dienst hat ein paar anonyme Methoden, sodass ich nicht authentifizierte Benutzer nicht einfach zurückweisen kann. Angesichts der Architektur von IIS und ASP.net ist das vielleicht einfach nicht möglich.

Antwort

0

Sie werden diese Anfrage wahrscheinlich in einer zweistufigen Anfrage stellen müssen. Eine Authentifizierungsanforderung vor dem Hochladen der Datei. Das ist eine Menge Gepäck, und der Endpunkt kann eine Anfrage erst bearbeiten, wenn sie fertig ist. Versuchen Sie eine separate Autorisierungsanfrage, bevor Sie die Datei hochladen. Wenn Ihre Anfrage erfolgreich ist, können Sie die Datei hochladen. Ist das eine gute Lösung?

+0

Dies ist im Wesentlichen was ich gerade mache. Ein Teil des Problems besteht darin, dass dieser Upload, wie implementiert, zu einem potenziellen DoS-Vektor wird; Ein nicht authentifizierter Benutzer kann große Datenmengen hochladen, die IIS pflichtgemäß auf die Festplatte spoolt, bevor er überprüft, ob der Endbenutzer überhaupt Anmeldeinformationen gesendet hat. – superstator

+0

Sie könnten einen Watchdog mit dem Hintergrundarbeiter in einem separaten Thread für diese Art von Anfrage implementieren. Ermitteln Sie die Anfrage und führen Sie den Watchdog aus. Sollte die Anfrage einen bestimmten Zeitraum überschreiten, Größe, Versuche, doppelte IP-Versuche, zu viele Uploads in einem bestimmten Zeitraum usw. Sie könnten dann die Anfrage zum Beenden zwingen. Ich bin mir sicher, dass es Möglichkeiten gibt. – trevster344

Verwandte Themen