Reputation: 1
I'm designing 2 websites. The first to upload images and the second to store the images as an image hosting (both of them are using asp.net mvc 5).
The domain name of the first website is: vinachannel.com
.
In the first website, I wanna send some images to the hosting via ajax:
var f = new FormData();
$.ajax({
url: 'https://myimagehosting.com/home/upload',
type: 'POST',
data: f,
processData: false,
contentType: false
}).done(function (data) {
// logic...
})
Action Upload
in Home
controller of the hosting:
[HttpPost]
public JsonResult Upload()
{
if (Request.Files.Count > 0)
{
// start uploading...
}
}
Now, my problem is: I wanna the image hosting accepts only the requests which are sent from vinachannel.com
. Just like:
[HttpPost]
public JsonResult Upload()
{
if (Request.Files.Count > 0 && Request.Url.AbsoluteUri.StartsWith("vinachannel.com"))
{
// start uploading...
}
}
or using regex:
var reg = new Regex(@"^(https://)?(www\.)?(vinachannel\.com)(.+)$");
if (Request.Files.Count > 0 && reg.IsMatch(Request.Url.AbsoluteUri))
{
// start uploading...
}
My question: How can I custom an attribute to validate all requests for action Upload
?
[VinaChannel] // only requests from site vinachannel.com
[HttpPost]
public JsonResult Upload()
{
// ...
}
UPDATE: (based on @David's comment and following the article)
public class VinaChannelFilter : ActionFilterAttribute, IActionFilter
{
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
var reg = new Regex(@"^(https://)?(www\.)?(vinachannel\.com)(.+)$");
if (reg.IsMatch(HttpContext.Current.Request.Url.AbsoluteUri))
{
// what's next here...?
}
this.OnActionExecuting(filterContext);
}
}
Upvotes: 0
Views: 846
Reputation: 218722
You may create a custom action filter which inspects the request headers and see where the request is coming from and use that values to determine, whether to allow /deny further processing. the Referer
header is the one you might want to use.
public class VerifyDomain : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var expectedHost = "domainnameyouwanttocheck";
var headers = filterContext.HttpContext.Request.Headers;
if (!String.IsNullOrEmpty(headers["Referer"])
&& new Uri(headers["Referer"]).Host == expectedHost)
{
base.OnActionExecuting(filterContext);
}
else
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
And decorate your action method/controller with the action filter
[VerifyDomain]
[HttpPost]
public ActionResult Upload()
{
// to do : return something
}
When this endpoint is being accessed from anywhere other than the value you have in the expectedHost
variable, the caller will get 401 Unauthorized
response. You may update the if condition to check for a list of expectedHost name's to support your local development environment as well.
Upvotes: 2
Reputation: 12618
Upload()
is on myimagehosting.com
, right? Then HttpContext.Current.Request.Url.AbsoluteUri
will return Uri on myimagehosting.com
domain, to get source address you need to get referrer: HttpContext.Current.Request.UrlReferrer.AbsolutePath
. But the problem is, it can be easily forged, so depending on your needs, you probably will have to implement more complex Authentication/Authorization logic
Upvotes: 1