Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Moderatore di Javascript L'avatar di ciro78
    Registrato dal
    Sep 2000
    residenza
    Napoli
    Messaggi
    8,514

    [c#] impedire accesso diretto al file tramite url ma scaricarlo

    Buongiorno a tutti,
    ho bloccato l'accesso diretto ai file aggiungendo un event handler

    codice:
    using System.IO;
    using System.Web;
    using System.Globalization;
        
    namespace MVPHacks
    {
    public class NoLeechImageHandler : IHttpHandler 
    {
     public void ProcessRequest(System.Web.HttpContext ctx) 
     {
         HttpRequest req = ctx.Request;
         string path = req.PhysicalPath;
         string extension = null;
         
         if (req.UrlReferrer != null && req.UrlReferrer.Host.Length > 0)
         {
          if (
    	  CultureInfo.InvariantCulture.CompareInfo.Compare(req.Url.Host, 
              req.UrlReferrer.Host, CompareOptions.IgnoreCase) != 0)
          {
              path = ctx.Server.MapPath("~/images/backoff.gif");
          }
         }            string contentType = null;
        
             ctx.Response.StatusDescription = "Image not found";
             ctx.Response.StatusCode = 404;
         
     }
     
         public bool IsReusable { get {return true; } }        
     }
    }
    
    
    
    
    <configuration>
        <system.web>
            <httpHandlers>
                <add verb="*" path="Document/*.*" type="MVPHacks.NoLeechImageHandler, MVPHacks "/>
            </httpHandlers>
        </system.web>
    </configuration>
    come vedete blocco l'accesso diretto a tutti i file presenti nella cartella ma vorrei comunque consentire
    la visualizzazione degli stessi passando attraverso una pagina ( che verifica il login e i ruoli)

    grazie
    Ciro Marotta - Programmatore JAVA - PHP
    Preferisco un fallimento alle mie condizioni che un successo alle condizioni altrui.


  2. #2
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Ciao Ciro,
    se hai già implementato l'autenticazione e sei logato nel sistema ti basta aggiungere un metodo che restituisce il file ed aggiungere l'attributo System.Web.Http.Authorize. Esempèio con immagine:
    codice:
            [System.Web.Http.Authorize]
            [HttpGet]
            public HttpResponseMessage GetImage(string id)
            {
                string path = HttpContext.Current.Server.MapPath("~/images");
                    string FilePath =Path.Combine(path, string.Format("{0}.jpg", id));
                if (!File.Exists(FilePath))
                    FilePath = Path.Combine(path, "default.jpg");
                HttpResponseMessage response = new HttpResponseMessage();
                response.Content = new StreamContent(new FileStream(FilePath, FileMode.Open, FileAccess.Read));
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
                return response;
            }
    ora ti basta raggiungere l'indirizzo dopo esserti logato, questo dipende da come gestisci il metodo, ad esempio in webApi potrebbe essere tipo: /api/miaApi/GetImage?id=miaImmagine, ma dipenderebbe dalla tua route.

  3. #3
    Moderatore di Javascript L'avatar di ciro78
    Registrato dal
    Sep 2000
    residenza
    Napoli
    Messaggi
    8,514
    grazie per la risposta

    alcune precisazioni: parliamo di dot net 2
    i file non devono essere accessibili direttamente

    es

    www.miosito.com/file.doc


    ovviamente non posso spostare la directory che contiene i file.

    ho fatto qualcosa ma tengo in ufficio il codice. domani la posto e magari la miglioriamo
    Ciro Marotta - Programmatore JAVA - PHP
    Preferisco un fallimento alle mie condizioni che un successo alle condizioni altrui.


  4. #4
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Quote Originariamente inviata da ciro78 Visualizza il messaggio
    grazie per la risposta

    alcune precisazioni: parliamo di dot net 2
    i file non devono essere accessibili direttamente

    es

    www.miosito.com/file.doc


    ovviamente non posso spostare la directory che contiene i file.

    ho fatto qualcosa ma tengo in ufficio il codice. domani la posto e magari la miglioriamo
    Recente il 2...
    Allora ti conviene fare una cosa del genere:
    codice:
        //IMPORTANTE: se usi la session devi far derivare la tua classe da IRequiresSessionState    
        public class NoLeechImageHandler : IHttpHandler, IRequiresSessionState
        {
            public void ProcessRequest(System.Web.HttpContext ctx)
            {
                HttpRequest req = ctx.Request;
                string serverPath = ctx.Server.MapPath(req.FilePath);
                //se il file non esiste 
                if (!File.Exists(serverPath))
                {
                    ctx.Response.StatusDescription = "Image not found";
                    ctx.Response.StatusCode = 404;
                    return;
                }
                //controllo che nella sessione ci sia una autenticazine. 
                //Potreesti farlo anche con il tuo sistema di autenticazione Forms ad esempio
                string path = (ctx.Session["Auth"] != null && (bool)ctx.Session["Auth"]) ?
                    serverPath :
                    Path.Combine(ctx.Server.MapPath("~/images"), "default.jpg");
                ctx.Response.ContentType = "image/jpg";
                ctx.Response.Clear();
                ctx.Response.BufferOutput = true;
                MemoryStream m = new MemoryStream();
                Image i = Image.FromFile(path);
                i.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg);
                ctx.Response.BinaryWrite(m.ToArray());
            }
            public bool IsReusable { get { return true; } }
        }
    In questo caso a chi chiama /images/* (/images/default.jpg o quello che vuoi) viene restituito il 404 se il file non esiste, il default.jpg se non è autenticato, e il file legittimo se è autenticato.
    da modificare eventualmente il tipo di autenticazione.
    Ultima modifica di U235; 09-11-2016 a 23:54

  5. #5
    Moderatore di Javascript L'avatar di ciro78
    Registrato dal
    Sep 2000
    residenza
    Napoli
    Messaggi
    8,514
    è esattamente quello che ho fatto. l'unica cosa che non mi si chiude la finestra del browser
    Ciro Marotta - Programmatore JAVA - PHP
    Preferisco un fallimento alle mie condizioni che un successo alle condizioni altrui.


  6. #6
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Quote Originariamente inviata da ciro78 Visualizza il messaggio
    è esattamente quello che ho fatto. l'unica cosa che non mi si chiude la finestra del browser
    Ciao, siamo OT visto che si parla di client, ma tieni presente che se la finestra la apri da codice javascript la puoi chiudere, ma se si tratta di una finestra aperta dall'utente il comportamento può variare da browser a browser se chiudi da codice. IE credo chieda conferma, mentre Chrome mi sa di no e Firefox probabilmente non lo consente (se non ricordo male). Quindi probabilmente se ti serve chiudere la scheda dopo una determinata procedura, potresti provare a lanciarla in una scheda separata, probabilmente riesci a chiuderla senza problemi.

  7. #7
    Moderatore di Javascript L'avatar di ciro78
    Registrato dal
    Sep 2000
    residenza
    Napoli
    Messaggi
    8,514
    beh apriamo un link tramite href niente di che.

    in php sono abituato che quando modifico l'header della pagina si chiude la stessa facendo solo scaricare il file. in questo caso resta aperta.
    Ciro Marotta - Programmatore JAVA - PHP
    Preferisco un fallimento alle mie condizioni che un successo alle condizioni altrui.


  8. #8
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    mi pareva strano chiedessi qualcosa di javascript... non avevo capito cosa intendessi. Dav per scontato volessi usare immagini (e quindi da visualizzare nel browser)
    modifica la risposta in questo modo:
    codice:
    ctx.Response.Clear();
    ctx.Response.ContentType = "application/octet-stream";            
    ctx.Response.AppendHeader("Content-Disposition", string.Format("attachment; filename={0}",serverPath));
    ctx.Response.TransmitFile(serverPath);
    ctx.Response.End();

  9. #9
    Moderatore di Javascript L'avatar di ciro78
    Registrato dal
    Sep 2000
    residenza
    Napoli
    Messaggi
    8,514
    Quote Originariamente inviata da U235 Visualizza il messaggio
    mi pareva strano chiedessi qualcosa di javascript... non avevo capito cosa intendessi. Dav per scontato volessi usare immagini (e quindi da visualizzare nel browser)
    modifica la risposta in questo modo:
    codice:
    ctx.Response.Clear();
    ctx.Response.ContentType = "application/octet-stream";            
    ctx.Response.AppendHeader("Content-Disposition", string.Format("attachment; filename={0}",serverPath));
    ctx.Response.TransmitFile(serverPath);
    ctx.Response.End();

    Ciao e grazie.
    Fatto ma non mi cambia nulla. La finestra del browser si apre e resta aperta.
    Ciro Marotta - Programmatore JAVA - PHP
    Preferisco un fallimento alle mie condizioni che un successo alle condizioni altrui.


  10. #10
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Quote Originariamente inviata da ciro78 Visualizza il messaggio
    Ciao e grazie.
    Fatto ma non mi cambia nulla. La finestra del browser si apre e resta aperta.
    Non saprei... puoi descrivere meglio lo scenario?
    Io ho provato questo e va, nel senso che funziona come mi aspetto e non apre una nuova scheda ma fa partire il download del file, se c'è e l'utente è autenticato, allora restituisce il file reale (nel link immagine.png), se non autenticato restituisce il file di default (qui default.jpg), mentre se non esiste il file ovviamente restituisce il 404, ma sempre nella stessa scheda senza aprirne altre.
    Per completezza ecco tutta la parte interessata:
    codice:
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test.aspx.cs" Inherits="WebApplication.test" %>
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">       
            <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="login" />
            <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="logout" />
            <a href="images/immagine.png">immagine.png</a>
            <a href="images/dasda">not found</a>
        </form>
    </body>
    </html>
    codice:
    public partial class test : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                if (Session["Auth"] == null)
                    Session.Add("Auth", false);
            }
            
            protected void Button1_Click(object sender, EventArgs e)
            {
                HttpContext.Current.Session["Auth"] = true;
            }
    
    
            protected void Button2_Click(object sender, EventArgs e)
            {
                HttpContext.Current.Session["Auth"] = false;
            }
        }
    codice:
    public class NoLeechImageHandler: IHttpHandler, IRequiresSessionState
        {
            public void ProcessRequest(System.Web.HttpContext ctx)
            {
                HttpRequest req = ctx.Request;
                string serverPath = ctx.Server.MapPath(req.FilePath);
                if (!File.Exists(serverPath))
                {
                    ctx.Response.StatusDescription = "Image not found";
                    ctx.Response.StatusCode = 404;
                    return;
                }
                string path = (ctx.Session["Auth"] != null && (bool)ctx.Session["Auth"])? 
                    serverPath:
                    Path.Combine(ctx.Server.MapPath("~/images"), "default.jpg");
                ctx.Response.Clear();
                ctx.Response.ContentType = "application/octet-stream";            
                ctx.Response.AppendHeader("Content-Disposition", string.Format("attachment; filename={0}", path));
                ctx.Response.TransmitFile(path);
                ctx.Response.End();
            }
    
    
            public bool IsReusable { get { return true; } }
        }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.