I have the following controller that, along with returning images, prevents direct linking:
我有以下控制器,连同返回的图像,防止直接链接:
public class ImageController : Controller
{
[HttpGet]
public ActionResult Details(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.
这行得通,但它有一种轻微的气味。有什么可以告诉我的吗?我最初对ControllerContext很有信心,但事实并非如此。
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>
}
1 个解决方案
#1
1
In your view generate an encrypted string containing id+file+datetime. In your img src @Url.Action pass this encrypted string.
在视图中生成包含id+file+datetime的加密字符串。在img src @Url中。操作传递这个加密字符串。
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.
在您的控制器中,解密该字符串以获得id & file & datetime。如果日期时间大于15秒,不要发送图像。如果密钥未被成功解密,则不提供图像。
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.
由于加密逻辑是私有的,其他人不能伪造请求,而且由于加密密钥中有datetime,所以可以在10-15秒内使链接过期,因此其他人不能对您的图像进行hotlink。
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"));
}
}
}
#1
1
In your view generate an encrypted string containing id+file+datetime. In your img src @Url.Action pass this encrypted string.
在视图中生成包含id+file+datetime的加密字符串。在img src @Url中。操作传递这个加密字符串。
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.
在您的控制器中,解密该字符串以获得id & file & datetime。如果日期时间大于15秒,不要发送图像。如果密钥未被成功解密,则不提供图像。
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.
由于加密逻辑是私有的,其他人不能伪造请求,而且由于加密密钥中有datetime,所以可以在10-15秒内使链接过期,因此其他人不能对您的图像进行hotlink。
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"));
}
}
}