问题
On my MVC3 site, I have a page that contains several links. These links all link back to a route on my site, with different ID values and are structured as such:
ie: www.mysite.com/links/33351/3
I'd like to take advantage of the MVC3's antiforgerytoken mechanism so that I can ensure that all requests to www.mysite.com/links/33351/3
from the link index page.
I'm familiar with how to add the token to a form, however these are all stand-alone links.
How can I accomplish this?
回答1:
You can't use the AntiForgeryToken for GET requests (i.e. clicking a link). For details - see Using MVC3's AntiForgeryToken in HTTP GET to avoid Javascript CSRF vulnerability.
One solution is to check the Request.UrlReferrer to ensure they came from your index page, but this is far from reliable.
Perhaps you could explain why you want to impose this restriction and I may be able to propose an alternative.
回答2:
Thanks to the comments above which helped me solve this.
Essentially, I created a Javascript function to process the item clicks. Each link on my page has an ID, so I simply passed the ID through to the JS function which submits the form:
<script type="text/javascript"> <!--
function doClick(itemID) {
document.getElementById('hid_ItemID').value = itemID;
// add whatever additional js type processing needed here - ie. analytics, etc.
document.forms[0].submit();
}
//-->
</script>
The form itself contains the MVC anti-forgery token tag:
@using (Html.BeginForm("DoRequest", "DoItemClickRq", FormMethod.Post, new { target = "_blank" }))
{
@Html.AntiForgeryToken()
<input type="hidden" id="hid_ItemID" name="hid_ItemID" value="" />
.
.
.
The controller method:
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult DoItemRequest()
{
int itemListID = 0;
int pagePositionNumber = 0;
int.TryParse(Request["hid_ItemID"], out itemListID);
. . .
回答3:
- For good design practice, all URLs in your application accessible via HTTP GET should be idempotent, meaning they should not change state no matter how many times they are accessed. It sounds like this may be the root of your problem, depending on the interpretation of "Navigating to the link performs some maintenance". Or you may be concerned about system load due to the maintenance. That is one reason why CSRF approaches have typically avoided handling GET requests.
- Exposing CSRF tokens in URLs, like session IDs, is bad security practice. URLs can leak into logfiles, proxy servers, especially if your site doesn't use 100% SSL.
Are the web crawlers standard well-behaved ones? If so, why not just use robots.txt to constrain the crawling behavior?
If that is not sufficient, perhaps you need to impose some sort of workflow restriction to prevent deep-link access (e.g. access to link X with session id A without going through steps 1 and 2 first is denied by your controller).
来源:https://stackoverflow.com/questions/8677933/using-the-mvc3-antiforgerytoken-with-links