In MVC, how do you determine the calling action?
I have the following controller that, along with returning images, prevents direct linking:
public class ImageController : Controller
{
[HttpGet]
public ActionResult Detai开发者_运维问答ls(string id, string file)
{
if (null == Request.UrlReferrer ||
Request.UrlReferrer.Authority != Request.Url.Authority ||
Request.UrlReferrer.AbsolutePath.ToLower() != Url.Action("Photos", "Home", new { id = id }).ToLower())
{
return base.File(Server.MapPath("/Content/images/notfound.jpg"));
}
// else process and return image
}
}
This works, but it has a slight smell. Is there something MVC-ier that will tell me this? I was initially hopeful about ControllerContext
, but that wasn't it.
Here is how I am calling this action from my view:
@foreach (var item in Model.Items)
{
<li>
<img src='@Url.Action("Details", "Image", new { id = Model.Project, file = item.ThumbnailPath })' />
</li>
}
In your view generate an encrypted string containing id+file+datetime. In your img src @Url.Action pass this encrypted string.
In your Controller, decrypt this string to obtain the id & file & datetime. If the datetime is greater than 15 seconds, dont serve the image. If the key is not decrypted successfully dont serve the image.
Since the encryption logic is private, others can not forge a request and since you have datetime in the encrypted key, you can expire the links in 10-15 seconds, so others can not hotlink to your images.
Hope this makes sense.
@foreach (var item in Model.Items) {
<li>
<img src='@Url.Action("Details", "Image", new { encryptedString= item.encryptedString})' />
</li> }
public class ImageController : Controller
{
[HttpGet]
public ActionResult Details(string encryptedString)
{
try
{
string[] values = DescryptString(encryptedString);
// values[0] = id
// values[1] = file
// values[2] = datetime
if(dateTime difference < 10 seconds )
return process and return image ;
else // link expired
return base.File(Server.MapPath("/Content/images/notfound.jpg"));
}
catch(DecodingException e)
{
// forged request
return base.File(Server.MapPath("/Content/images/notfound.jpg"));
}
}
}
精彩评论