This is a migrated thread and some comments may be shown as answers.

Anti-Forgery in MVC Wrapper for Ajax binding using request header

5 Answers 359 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
Gary Davis
Top achievements
Rank 2
Gary Davis asked on 14 Aug 2013, 05:53 PM
I did not see any solutions in the forums for sending the Anti-Forgery token as a header (instead of JSON data) in an MVC server control (grid) datasource.

The page has no form but that is OK.

My solution works but I don't know if it is optimal.

The ajaxSetup affects all jQuery Ajax and Posts and that is what Kendo is doing so it gets a chance to locate the <input> value inserted by the Html.AntiForgeryToken() and add it as a request header for the Ajax call.

It would be nice if the DataSource had a Headers() extension like it does the Data() to do this.

Gary Davis
<%: Html.AntiForgeryToken() %>
 
<script type="text/javascript">
        $(function () {
            // For the Kendo Ajax call for paging, etc.
            $.ajaxSetup({ // See: ValidateAntiForgeryTokenOnAllPostsAttribute
                "beforeSend": function (xhr) { // Affects all Ajax & Posts
                    var securityToken = $("[name=__RequestVerificationToken]").val();
                    xhr.setRequestHeader("__RequestVerificationToken", securityToken);
                }
            });
        });
</script>    

5 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 16 Aug 2013, 01:20 PM
Hello,

The wrapper does not support setting the request headers. Besides setting the options globally, I can also suggest to get the Grid object after it has been initialized and modify the transport options:

$(function () {
    var grid = $("#grid").data("kendoGrid"),
        transport = grid.dataSource.transport;
 
    transport.options.read.beforeSend = myFunction;
});
Regards,
Daniel
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Gary Davis
Top achievements
Rank 2
answered on 16 Aug 2013, 02:19 PM
Thanks. That works and is a useful technique to get to the transport property of the dataSource for those of us using the wrapper.

Gary
0
Gary Davis
Top achievements
Rank 2
answered on 08 Sep 2014, 02:08 PM
I modified my grid so that on the initial display of the page, it issues an Ajax request to get the 1st page's grid data instead of having the entire grid in the model.

The grid works fine except the transport.options.read.beforeSend() function is not called on that initial request so the __RequestVerificationToken is not added to the request header. For any other Ajax requests like sort or page, the function is called and the token is added to the header just fine.

var grid = $("#Grid").data("kendoGrid");
var transport = grid.dataSource.transport;
transport.options.read.beforeSend = function(xhr) {
    var securityToken = $("[name=__RequestVerificationToken]").val();
    xhr.setRequestHeader("__RequestVerificationToken", securityToken);
};


Do you have a solution for this issue?

Thanks.
0
Gary Davis
Top achievements
Rank 2
answered on 08 Sep 2014, 02:37 PM
I think I found the solution from http://www.telerik.com/forums/issue-with-antiforgerytoken

The read is called before the beforeSend() is set up. So I set the grid property AutoBind(false) and after I set up the beforeSend(), I call the read that would have been called by AutoBind.

‚Äč
var grid = $("#Grid").data("kendoGrid");
var transport = grid.dataSource.transport;
transport.options.read.beforeSend = function(xhr) {
    var securityToken = $("[name=__RequestVerificationToken]").val();
    xhr.setRequestHeader("__RequestVerificationToken", securityToken);
};
grid.dataSource.read(); // Now it is ok to trigger read since beforeSend is now set up (autobind would have been too early)
0
Daniel
Telerik team
answered on 10 Sep 2014, 08:45 AM
Hello again Gary,

Indeed, the initial binding should be prevented in order to assign the beforeSend handler. Also, although it will require setting a bit more configuration options, in the latest versions we introduced a Custom builder for the dataSource that can be used to specify the beforeSend handler e.g.
.DataSource(dataSource => dataSource
    .Custom()
    .Type("aspnetmvc-ajax")
    .Transport(transport => transport
        .Read(new
        {
            url = Url.Action("Action", "Controller"),
            beforeSend = new Kendo.Mvc.ClientHandlerDescriptor
            {
                   HandlerName = "beforeSend"
            }               
        })
    )
    .Schema(schema => schema
        .Data("Data")
        .Total("Total")
        .Errors("Errors")
    )
    .ServerPaging(true)
    .ServerSorting(true)
    .ServerFiltering(true)
    .ServerGrouping(true)
    .ServerAggregates(true)
)
<script>
    function beforeSend(xhr) {
        var securityToken = $("[name=__RequestVerificationToken]").val();
        xhr.setRequestHeader("__RequestVerificationToken", securityToken);
    };
</script>


Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Tags
Data Source
Asked by
Gary Davis
Top achievements
Rank 2
Answers by
Daniel
Telerik team
Gary Davis
Top achievements
Rank 2
Share this question
or