2010-04-15 14 views
6

Mam działanie, które musi odczytać plik z bezpiecznej lokalizacji, więc muszę użyć personifikacji, aby odczytać plik.Podszywanie się w ASP.NET MVC

ten kod działa:

[AcceptVerbs(HttpVerbs.Get)] 
public ActionResult DirectDownload(Guid id) 
{ 
    if (Impersonator.ImpersonateValidUser()) 
    { 
     try 
     { 
      var path = "path to file"; 
      if (!System.IO.File.Exists(path)) 
      { 
       return View("filenotfound"); 
      } 

      var bytes = System.IO.File.ReadAllBytes(path); 
      return File(bytes, "application/octet-stream", "FileName"); 
     } 
     catch (Exception e) 
     { 
      Log.Exception(e); 
     }finally 
     { 
      Impersonator.UndoImpersonation(); 
     } 
    } 
    return View("filenotfound"); 
} 

Jedyny problem z powyższym kodzie jest to, że muszę przeczytać cały plik do pamięci i będę mieć do czynienia z bardzo dużymi plikami, więc nie jest to dobre rozwiązanie. Ale jeśli mam wymienić te 2 linie:

var bytes = System.IO.File.ReadAllBytes(path); 
return File(bytes, "application/octet-stream", "FileName"); 

z tym:

return File(path, "application/octet-stream", "FileName"); 

to nie działa i pojawia się komunikat o błędzie:

dostęp do ścieżki „C: \ projects \ uploads \ 1 \ aa2bcbe7-ea99-499d-add8-c1fdac561b0e \ Untitled 2.csv 'jest zabronione.

Chyba wykorzystaniem wyników plik o ścieżce, próbuje otworzyć plik w późniejszym czasie na żądanie rurociągu, kiedy mam już „cofniętą” personifikacji.

Pamiętaj, że kod podszywania działa, ponieważ mogę odczytać plik z tablicy bajtów. Co chcę zrobić, to przesłać plik do klienta.

Masz pomysł, jak sobie z tym poradzić?

Z góry dziękuję.

Odpowiedz

4

Możesz spróbować napisać niestandardowy FilePathResult:

public class ImpersonatingFileResult : FilePathResult 
{ 
    public ImpersonatingFileResult(string fileName, string contentType) 
     : base(fileName, contentType) 
    { } 

    protected override void WriteFile(HttpResponseBase response) 
    { 
     // TODO : Start impersonation 
     response.TransmitFile(FileName); 
     // TODO : Rollback impersonation 
    } 
} 

i w kontrolerze:

return new ImpersonatingFileResult(path, "application/octet-stream"); 
+0

To działało świetnie. Zmieniłem go trochę, ponieważ otrzymywałem wyjątek ... Impersonator.ImpersonateValidUser(); response.WriteFile (FileName); response.Flush(); response.End(); Impersonator.UndoImpersonation(); – Emad

+0

Tak, to dobry początek.Jednak w niektórych wersjach usług IIS będą generowane błędy "Nieprawidłowy uchwyt", które są oparte na udostępnianiu pliku (a nie na podszywaniu się pod użytkownika). – Greg

1

lubię Darin odpowiedź, ale pomija logikę personifikacji, a to generuje błąd w IIS 7 ...

Dodałem więc kod podszywania się, jak mogłem, wykorzystując N Pakiet uget SimpleImpersonation.

Wprowadzono także kilka zmian w IIS 7, aby zapobiec błędowi obsługi.

public class ImpersonatingFileResult : FilePathResult 
{ 
    public ImpersonatingFileResult(string fileName, string contentType) 
     : base(fileName, contentType) 
    { } 

    protected override void WriteFile(HttpResponseBase response) 
    { 
     using (SimpleImpersonation.Impersonation.LogonUser(domain: "SomeDomain", username: "SomeUser", password: "SomePassword", logonType: SimpleImpersonation.LogonType.NewCredentials)) 
     { 
      response.Clear(); 
      response.ContentType = base.ContentType; 
      response.AddHeader("Content-Disposition", "attachment; filename=" + System.IO.Path.GetFileName(base.FileName)); 
      response.TransmitFile(FileName); 
      response.Flush(); 
     } 
    } 

a następnie użycie go z kontrolerem:

 return new ImpersonatingFileResult(someFilePath, "Application/pdf"); 

Powyższe jest do pobierania pliku, ale jeśli chcesz, aby go wyświetlić, a następnie trzeba określić „inline”.

  response.Clear(); 
      response.ContentType = base.ContentType; 
      response.AddHeader("Content-Disposition", "inline; filename=\"" + System.IO.Path.GetFileName(base.FileName) + "\""); 
      response.TransmitFile(FileName); 
      response.Flush(); 
+0

To jest świetna odpowiedź, dziękuję! –

Powiązane problemy