Asp.net mvc 使用ASP.net MVC从不同目录路由静态文件,无需IIS更改和身份验证

Asp.net mvc 使用ASP.net MVC从不同目录路由静态文件,无需IIS更改和身份验证,asp.net-mvc,asp.net-mvc-3,asp.net-mvc-routing,httpmodule,mvcroutehandler,Asp.net Mvc,Asp.net Mvc 3,Asp.net Mvc Routing,Httpmodule,Mvcroutehandler,让我在以下位置为应用程序的单个用户存储内容: C:\Files{GUID}\ 这些文件可能类似于: C:\Files{GUID}\bunny.jpg C:\Files{GUID}\unicorn.html 最终用户应该得到一个“友好”的url http://domain.com/files/{GUID}/bunny.jpg 该url必须以某种方式通过控制器、httpmodule或其他东西才能被授权查看该文件。这些权限可能会每天更改,因此需要经常检查文件的权限 从我所阅读的内容来看,这是完

让我在以下位置为应用程序的单个用户存储内容:

  • C:\Files{GUID}\
这些文件可能类似于:

  • C:\Files{GUID}\bunny.jpg
  • C:\Files{GUID}\unicorn.html
最终用户应该得到一个“友好”的url

http://domain.com/files/{GUID}/bunny.jpg

该url必须以某种方式通过控制器、httpmodule或其他东西才能被授权查看该文件。这些权限可能会每天更改,因此需要经常检查文件的权限

从我所阅读的内容来看,这是完全可能的,但我不确定下一步该编写什么代码,或者是否有人对此有任何见解。HttpModule还是Controller?我对需要发生什么感到困惑

该url必须以某种方式通过控制器、httpmodule或其他东西才能被授权查看该文件。这些权限可能会每天更改,因此需要经常检查文件的权限

你不知道的东西有个名字。它被称为授权操作过滤器

首先,假设您已经注册了一个自定义路由来为这些文件提供服务:

routes.MapRoute(
    "MyImagesRoute",
    "files/{id}/{name}",
    new { controller = "Files", action = "Index" }

    // TODO: you could constrain the id parameter to be a GUID.
    // Just Google for a Regex that will match a GUID pattern and put here
    // as route constraint
);
当然,还有一个相应的控制器为他们服务:

public class FilesController: Controller
{
    public ActionResult Index(Guid guid, string name)
    {
        var path = @"C:\files";
        var file = Path.Combine(path, guid.ToString(), name);
        file = Path.GetFullPath(file);
        if (!file.StartsWith(path))
        {
            // someone tried to be smart and send
            // files/{Guid}/..\..\creditcard.pdf as parameter
            throw new HttpException(403, "Forbidden");
        }

        // TODO: adjust the mime type based on the extension
        return File(file, "image/png");
    }
}
不幸的是,在这个阶段没有任何东西阻止用户ALPHA请求用户BETA的文件,对吗?这就是你想处理的情况,不是吗

因此,让我们编写一个自定义授权属性来保护此控制器操作:

public class MyAuthorizeAttribute: AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            // The user is not authenticated or doesn't have 
            // permissions to access this controller action
            return false;
        }

        // at this stage we know that there's some user authenticated

        // Let's get the Guid now from our route:
        var routeData = httpContext.Request.RequestContext.RouteData;

        var id = routeData.Values["id"] as string;
        Guid guid;
        if (!Guid.TryParse(id, out guid))
        {
            // invalid Guid => no need to continue any further, just deny access
            return false;
        }

        // Now we've got the GUID that this user is requesting

        // Let's see who this user is:
        string username = httpContext.User.Identity.Name;

        // and finally ensure that this user
        // is actually the owner of the folder
        return IsAuthorized(username, guid);
    }

    private bool IsAuthorized(string username, Guid guid)
    {
        // You know what to do here: hit your data store to verify
        // that the currently authenticated username is actually
        // the owner of this GUID
        throw new NotImplementedException();
    }
}
然后让我们用这个授权属性来修饰控制器操作:

public class FilesController: Controller
{
    [MyAuthorize]
    public ActionResult Index(Guid guid, string name)
    {
        // at this stage we know that the currently authenticated user
        // is authorized to access the file.

        var path = @"C:\files";
        var file = Path.Combine(path, guid.ToString(), name);
        file = Path.GetFullPath(file);
        if (!file.StartsWith(path))
        {
            // someone tried to be smart and send
            // files/{Guid}/..\..\creditcard.pdf as parameter
            throw new HttpException(403, "Forbidden");
        }

        var file = Path.Combine(@"c:\files", guid.ToString(), name);
        // TODO: adjust the mime type based on the extension
        return File(file, "image/png");
    }
}

谢谢你,达林,你是最棒的,我从专业的角度爱你。