[CLOSED] XSRF AntiForgeryToken with AjaxProxy

  1. #1

    [CLOSED] XSRF AntiForgeryToken with AjaxProxy

    We are using a Store (for a GridPanel) which is loaded using an AjaxProxy.

    However, [ValidateAntiForgeryToken] is not supported.

    This web-page provides a method to add the AntiForgeryToken checking for JSON requests. We have successfully added the new class and applied the [ValidateJsonAntiForgeryTokenAttribute] to our controller. We have also added additional fields to the header of the RESTPROXY.

    Question: Can we use Html.X().AntiForgeryField() to provide the value of input["__RequestVerificationToken"] to the new field we have added to the AJAX header?

     .Store(
                    Html.X().StoreForModel().Control(s =>
                    {
                        s.AutoSync = true;
                        s.Proxy.Add(
                            new RestProxy
                            {
                                AppendAction = false,
                                @*ActionMethods = { Read = Ext.Net.HttpMethod.POST, Create = Ext.Net.HttpMethod.POST },*@
                                Reader = {
                                    new JsonReader {
                                        RootProperty = "data",
                                        MessageProperty = "message"
                                    }
                                },
                                API =
                                {
                                    Read = Url.Action("Read"),
                                    Update = Url.Action("Update"),
                                    Create = Url.Action("Create"),
                                    Destroy = Url.Action("Destroy")
                                },
                                Writer = {
                                    new JsonWriter
                                    {
                                        AllowSingle = true
                                    }
                                },
                                Headers = {
                                            new Ext.Net.Parameter("__RequestVerificationToken", Html.X().AntiForgeryField())
                                          }
                            }
                        );
                        s.Listeners.Write.Fn = "onWrite";
                        s.Listeners.Write.Delay = 1;
                    })
                )
    Last edited by Daniil; Aug 12, 2015 at 11:17 AM. Reason: [CLOSED]
  2. #2
    Hello @PocketPrograms!

    AntiForgeryField() accepts the 'Name()' and 'Value()' properties so you can specify custom fields and values to it. I believe this is what you're looking for.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Hi Fabricio thanks for your help,

    we tried using Html.X().AntiForgeryField().Value():

                                Headers = {
                                            new Ext.Net.Parameter("__RequestVerificationToken", Html.X().AntiForgeryField().Value())
                                          }

    but get this error

    Compiler Error Message: CS1501: No overload for method 'Value' takes 0 arguments
    The help for .Value() states "value to initialize this field with". Is there another method to get the value of the AntiForgeryField ?
  4. #4
    Hello everybody,

    Yes, .Value() is not to get a value, it is only for setting.

    In the post that you mentioned a token is retrieving by this code:
    var token = $('input[name=""__RequestVerificationToken""]').val();
    With AntiForgeryField I would recommend:
    @X.AntiForgeryField().ID("AntiForgeryField")
    and
    new Ext.Net.Parameter("__RequestVerificationToken", "App.AntiForgeryField.getValue()", ParameterMode.Raw)
    Here is a small test case. The URL is fake. The sample is meant to just check that the AntiForgeryField's value goes with a request.

    Example
    @{
        var X = Html.X();
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>Ext.Net.MVC v3 Example</title>
    </head>
    <body>
        @X.ResourceManager()
    
        @X.AntiForgeryField().ID("AntiForgeryField")
    
        @(X.Button()
            .Text("Submit")
            .DirectEvents(events =>
            {
                events.Click.Url = "someUrl";
                events.Click.ExtraParams.Add(new Ext.Net.Parameter("__RequestVerificationToken", "App.AntiForgeryField.getValue()", ParameterMode.Raw));
            })
        )
    </body>
    </html>
  5. #5
    Hi Daniil,

    thanks for your suggestion.

    We have tried the following without success:

    1. With this this variant the REST call to READ the data doesn't get triggered:

        Headers = {
                    new Ext.Net.Parameter("__RequestVerificationToken", "App.AntiForgeryField.getValue()",ParameterMode.Raw)
                  }
    2. We tried this, but the debugger shows that the value of the header field is the text "App.AntiForgeryField.getValue()", not the value of the field:
     Headers = {
                    new Ext.Net.Parameter("__RequestVerificationToken", "App.AntiForgeryField.getValue()",ParameterMode.Value)
                  }
    3. We remove the quotes around App.AntiForgeryField.getValue() and get error Cannot perform runtime binding on a null reference
        Headers = {
                    new Ext.Net.Parameter("__RequestVerificationToken", App.AntiForgeryField.getValue(),ParameterMode.Raw)
                  }
    The complete view is now as follows:
    @model IEnumerable<Customer>
    @{
        ViewBag.Title = "Customers";
        //Layout = "~/Views/Shared/_BaseLayout.cshtml";
    }
    
    @Html.X().ResourceManager().Locale("client")
    @Html.X().AntiForgeryField().ID("AntiForgery")
    <script>
        var onWrite = function (store, operation) {
            var record = operation.getRecords()[0],
                name = Ext.String.capitalize(operation.action),
                verb;
    
            if (name == 'Destroy') {
                verb = 'Destroyed';
            } else {
                verb = name + 'd';
            }
    
            Ext.net.Notification.show({ title: name, html: Ext.String.format("{0} customer: {1}<br/>{2}", verb, record.getId(), operation.getResultSet().message) });
        }
    </script>
    
    <h1>Customers</h1>
    @(Html.X().Store()
                .ID("CountryStore")
                .AutoLoad(true)
                .Model(Html.X().Model()
                    .IDProperty("Id")
                    .Fields(
                        new ModelField("id", ModelFieldType.String) { Mapping = "Id" },
                        new ModelField("name", ModelFieldType.String) { Mapping = "Name" }
                    )
                )
                .Proxy(Html.X().AjaxProxy()
                    .Url(Url.Action("GetCountries"))
                    .Reader(Html.X().JsonReader().RootProperty("data"))
                )
     )
    @(Html.X().GridPanel()
                .Icon(Icon.Table)
                .Frame(true)
                .Title("Customers")
                .Height(800)
                .Width(1500)
                .Store(
                    Html.X().StoreForModel().Control(s =>
                    {
                        s.AutoSync = true;
                        s.Proxy.Add(
                            new RestProxy
                            {
                                AppendAction = false,
                                @*ActionMethods = { Read = Ext.Net.HttpMethod.POST, Create = Ext.Net.HttpMethod.POST },*@
                                Reader = {
                                    new JsonReader {
                                        RootProperty = "data",
                                        MessageProperty = "message"
                                    }
                                },
                                API =
                                {
                                    Read = Url.Action("Read"),
                                    Update = Url.Action("Update"),
                                    Create = Url.Action("Create"),
                                    Destroy = Url.Action("Destroy")
                                },
                                Writer = {
                                    new JsonWriter
                                    {
                                        AllowSingle = true
                                    }
                                },
        Headers = {
                    new Ext.Net.Parameter("__RequestVerificationToken", "App.AntiForgeryField.getValue()",ParameterMode.Raw)
                  }
                            }
                        );
                        s.Listeners.Write.Fn = "onWrite";
                        s.Listeners.Write.Delay = 1;
                    })
                )
                .ColumnModel(
                    @*Html.X().ColumnFor(Model, m => m.customer_id)
                                .ToBuilder<Column.Builder>()
                                .Width(40)
                                .Renderer("return record.phantom ? '' : value;"),*@
                    Html.X().ColumnFor(Model, m => m.firstname).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.lastname).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.email_address).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.telephone).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.company_name).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.street_address).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.suburb).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.postcode).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.city).ToBuilder<Column.Builder>().Flex(1),
                            Html.X().ColumnFor(Model, m => m.state).ToBuilder<Column.Builder>().Flex(1),
                        Html.X().ColumnFor(Model, m => m.country_name)
                            .ToBuilder<Column.Builder>()
                            .Width(250)
                            .Editor(Html.X().ComboBox()
                                                .ID("ComboBoxCountry")
                                                .TypeAhead(true)
                                                .QueryMode(DataLoadMode.Local)
                                                .ForceSelection(true)
                                                .TriggerAction(TriggerAction.All)
                                                .EmptyText("Select a country")
                                                .StoreID("CountryStore")
                                                .ValueField("name")
                                                .DisplayField("name")
                                    )
                        )
                        .TopBar(
                            Html.X().Toolbar()
                                .Items(
                                    Html.X().Button()
                                        .Text("Add")
                                        .Icon(Icon.Add)
                                        .Handler("this.up('grid').store.insert(0, new Customer());this.up('grid').editingPlugin.startEdit(0, 0);"),
                                    Html.X().Button()
                                        .ItemID("btnRemove")
                                        .Text("Delete")
                                        .Icon(Icon.Exclamation)
                                        .Handler("this.up('grid').deleteSelected();")
                                )
                        )
                        .Plugins(
                            Html.X().RowEditing()
                                .Listeners(l =>
                                {
                                    l.CancelEdit.Handler = "if(e.record.phantom){e.store.remove(e.record);}";
                                })
                        )
    )
    Can you please advise how to get the value of the AntiForgeryField into the header.
  6. #6
    1. With this this variant the REST call to READ the data doesn't get triggered:
    Probably, there is a JavaScript error and I guess what exactly. Do you see any errors in the console? Error messages are ofter very helpful to understand what is going on.

    If you set .ID("AntiForgery"), you should use "App.AntiForgery.getValue()" instead of "App.AntiForgery.getValue()".
  7. #7
    Thanks Daniil,

    that was the issue. We changed App.AntiForgeryField.getValue() to App.AntiForgery.getValue().

Similar Threads

  1. Mix use of PageProxy & AjaxProxy
    By vincent_van in forum 2.x Help
    Replies: 2
    Last Post: Jun 06, 2014, 8:43 AM
  2. why AjaxProxy dose not run?
    By sclsch in forum 2.x Help
    Replies: 1
    Last Post: Apr 16, 2013, 1:27 AM
  3. [CLOSED] AntiForgeryToken
    By jpadgett in forum 2.x Legacy Premium Help
    Replies: 3
    Last Post: Feb 12, 2013, 1:30 PM
  4. Old HttpProxy and new AjaxProxy
    By retto in forum 2.x Help
    Replies: 0
    Last Post: Jan 02, 2013, 8:59 PM
  5. AjaxProxy Example
    By yash.kapoor in forum 2.x Help
    Replies: 8
    Last Post: Dec 20, 2012, 9:39 AM

Tags for this Thread

Posting Permissions