0

Some of our site's images are "private" and should only be served to authenticated and authorized users.

So they are located in /App_Data, and are rendered via this secured action:

//[ChildActionOnly]
[Authorize]
[HttpGet]
[Route("Image")]
public virtual FileResult Image(string path) {
  return base.File(Server.MapPath(path), "image/jpg");
}

In a view, I have <img src="@Url.Action(Image(...))"> which correctly serves that "private" image. No public user can see it.

Problem is I don't want my authenticated users to be able to navigate to it directly, so I added the [ChildActionOnly] attribute. But when I do that, it fails to load.

How can I serve these images to private users, but make it inaccessible from a request?

h bob
  • 3,610
  • 3
  • 35
  • 51

1 Answers1

1

ChildActionOnly means that the action can only be called via Html.Action. Since you can't load an image that way, it will never work. If you want the action protected, then all you need is the Authorize attribute:

[Authorize]
[HttpGet]
[Route("Image")]
public virtual FileResult Image(string path) {
    return base.File(Server.MapPath(path), "image/jpg");
}

UPDATE

I think I understand what you mean now. You're saying you only want to be able load it on the page, but you don't want some one to be able to copy the href and load it in a separate window or tab? Is that correct? If so, then unfortunately, that's simply not possible. A request is a request, whether it's done via HTML on your page or manually via a user, there's no difference.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Yes I have authorization at the class level, I'll edit the Q. But this ensures that unauthorized users can't access the image. But unfortunately authorized users can navigate to it directly. – h bob Dec 08 '15 at 15:10
  • Regarding update, yes I feared that. I suppose the only way to handle this use case is to wrap the image in a partial view, and control when/how it is rendered. But that's too much effort in my case. – h bob Dec 08 '15 at 16:09
  • 1
    That doesn't really buy you anything. Once the partial is rendered, the user can still just get the image link and access it directly whenever they like. The best you can do is protect the image from unauthorized access. If the user is allowed to see it at all, they can also access it directly. That's just how it works. – Chris Pratt Dec 08 '15 at 18:10