Closed orchardbot closed 9 years ago
@Piedone commented:
This is expected, a POST automatically requires a token. You can add it manually when building the AJAX request, or if you submit a form already having it.
2LM commented:
I'm sorry, but I think there's some misunderstanding, a POST indeed requires a token, but passing a token only works when Module.txt contains "AntiForgery: disabled".
When passing a completely valid token when Module.txt contains "AntiForgery: enabled", you receive the error "A required anti-forgery token was not supplied or was invalid."
You can test this by using the sample module of Ryan Keeter at http://ryankeeter.com/ajax-and-anti-forgery-tokens-in-orchard-cms.
His module works perfectly, simply because his Module.txt contains "AntiForgery: disabled". If you change that to "enabled", it no longer works.
It might be that I have a wrong understanding of the "AntiForgery" setting in Module.txt, but to my understanding when this is "enabled", I should be able to do an AJAX POST when passing a valid token. When this is "disabled", I think the passed token should be ignored. Even this is not the case, as the system also errors when the setting in Module.txt is "disabled" and you don't pass a valid token.
Please shed some light onto this as to my belief, something isn't really working as expected here...
@Piedone commented:
I think you understand that config option correctly. But I'm surprised that it doesn't work for you, the Shoutbox module (http://orchardshoutbox.codeplex.com/) has a form posted through AJAX and it works as expected, sending a token (used e.g. here: http://english.orchardproject.hu/).
2LM commented:
I had a look at the Shoutbox project, and the biggest difference in what I want to do and Shoutbox is that Shoutbox uses a form post, and the aforementioned module of Rian Keeter is using an AJAX post using knockoutJS.
Could it be that a $.ajax() call passing an object containing a __RequestVerificationToken property results in different behavior in regards to the Module.txt setting? It sure seems so...
@Piedone commented:
Take a look again :-). Although the Shoutbox module has a standard form, there is some JS that overrides its submit event and posts the form through AJAX. That means the form data, including the token is not built by hand, but a standard form is serialized for posting. That shouldn't make any difference in terms of handling the token though.
2LM commented:
Hi,
Thanks for persisting :) I just had a new look and I think I may have found the issue, of which I'm not really sure whether it's intended...
In module Example.Forgery of Ryan Keeter, the following is used:
<fieldset>
<legend>
Create Person
</legend>
<div>
@Html.LabelFor(m => m.FirstName, T("First Name"))
@Html.TextBoxFor(m => m.LastName, new {Data_Bind = "value: FirstName"})
</div>
<div>
@Html.LabelFor(m => m.LastName, T("Last Name"))
@Html.TextBoxFor(m => m.LastName, new {Data_Bind = "value: LastName"})
</div>
<div style="padding-top: 10px;">
<button type="submit" data-bind="click: AddPerson">Add Person</button>
</div>
</fieldset>
var person = new Person({
FirstName: self.FirstName(),
LastName: self.LastName(),
__RequestVerificationToken:'@Html.AntiForgeryTokenValueOrchard()'
});
$.ajax(
"/Example.Forgery/Person/Create", {
data: ko.toJSON(person),
type: "post",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (result) { alert(result); }
}
);
The use of @Html.AntiForgeryTokenValueOrchard() works perfectly as long as Module.txt contains "AntiForgery: disabled". When changing this to "enabled", this fails miserably :(
When I change Ryan's code to use "@using (Html.BeginFormAntiForgeryPost())" wrapped around his fieldset, and change his post data to use the hidden __RequestVerificationToken field as follows, everyting works as expected:
var person = new Person({
FirstName: self.FirstName(),
LastName: self.LastName(),
__RequestVerificationToken:$(':input[name="__RequestVerificationToken"]').val(); //'@Html.AntiForgeryTokenValueOrchard()'
});
While I can see the result of it working now, I'm a bit confused as to why "@Html.AntiForgeryTokenValueOrchard()" doesn't work. Is this a bug or am I missing something here?
@bleroy commented:
Also, make sure you have a machine key.
2LM commented:
Thanks for your input Bertrand, what is the machineKey for? I suspect it should be placed in machine.config or something, and if so, what with shared hosting?
Apart from that, do you have any thoughts on why "@Html.AntiForgeryTokenValueOrchard()" doesn't work with knockoutJS AJAX Posts and "@using (Html.BeginFormAntiForgeryPost())" does?
@bleroy commented:
The machine key is used for all crypto that needs to be done on your site. If you don't specify it, it can be regenerated, destroying your ability to validate previously rendered forms. See http://docs.orchardproject.net/Documentation/Setting-up-a-machine-key (and the release notes)
2LM commented:
Superb, I was unaware of this... Thanks!
@bleroy commented:
May I close this?
2LM commented:
Well, my overall issue is resolved, but I'm still clueless on why "@Html.AntiForgeryTokenValueOrchard()" doesn't work with knockoutJS AJAX Posts and "@using (Html.BeginFormAntiForgeryPost())" does?
2LM commented:
I just tried to add a machineKey to my web.config as generated at aspnetresources.com:
By adding this to the web.config, Orchard seems to be unable to authenticate or something, as I can't get to the site or admin anymore and am redirected to http://localhost:32321/Users/Account/AccessDenied?ReturnUrl=%2f
@bleroy commented:
You should never publish a crypto key publicly. This is negating the whole point of having one.
2LM commented:
Yes, I know, this is not my crypto key, I just copied it in from aspnetresources for illustration. Problem still remains though, any ideas? I've seen this behavior quite lot with Orchard lately, whenever something's wrong, I just get a redirection to the below url, and nothing to be found in the logs... Pretty frustrating to debug I must say. Is there some way to get info about these issues rather than getting redirected to the below, which is even an empty white page, I must add:
http://localhost:32321/Users/Account/AccessDenied?ReturnUrl=%2f
@bleroy commented:
I don't know, I've never seen it. File another bug with good repro steps?
2LM created: https://orchard.codeplex.com/workitem/19005
When doing an AJAX Post to a controller in a custom module, the error "A required anti-forgery token was not supplied or was invalid." is thrown. This only works when Module.txt contains "AntiForgery: disabled".
You can test this by following the blog post of Ryan Keeter about the AntiForgeryToken and AJAX, or even better, use his example module. You will see that his module only works because Module.txt contains "AntiForgery: disabled". If you change this to "enabled", the above error occurs: http://ryankeeter.com/ajax-and-anti-forgery-tokens-in-orchard-cms