是否有可能/右2不同的形式使用多个@ Html.AntiForgeryToken()在一个页面? [英] Is it possible/right to use multiple @Html.AntiForgeryToken() in 2 different forms in one page?

查看:142
本文介绍了是否有可能/右2不同的形式使用多个@ Html.AntiForgeryToken()在一个页面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直面临着严重的问题, @ Html.AntiForgeryToken()。我有一个寄存器控制器,它有一个创建视图中创建/注册新会员。出于这个原因我使用了 @ Html.AntiForgeryToken()没有在我的主要形式提交使用任何盐。现在我想验证用户名,如果它已经在我的用户名文本框的模糊事件在数据库上存在。对于此验证我写了一个名为'验证'新的控制器,并写了不断的验证盐的方法:

  [HttpPost]
    [ValidateAntiForgeryToken(盐= @ ApplicationEnvironment.SALT)
    公众的ActionResult用户名(字符串日志){
        尝试{
            如果(日志== NULL || log.Length 3;)
                返回JSON(日志,JsonRequestBehavior.AllowGet);            VAR成员= Membership.GetUser(日志);            如果(成员== NULL){
                //字符串userPattern = @^([A-ZA-Z])[A-ZA-Z _-] * [\\ w _-] * [\\ S] $ | ^([A-ZA-Z])[0 -9 _-] * [\\ S] $ | ^ [A-ZA-Z] * [\\ S] $;
                字符串userPattern =[A-ZA-Z] [A-ZA-Z0-9 ._] {3,80};
                如果(Regex.IsMatch(日志,userPattern))
                    返回JSON(日志,JsonRequestBehavior.AllowGet);
            }        }赶上(例外前){
            CustomErrorHandling.HandleErrorByEmail(例如,验证LOGNAME());
            返回JSON(日志,JsonRequestBehavior.AllowGet);
        }
        //发现虚假ê
        返回JSON(日志,JsonRequestBehavior.AllowGet);    }

方法是工作的罚款。我曾与HTTP检查获取注释而不 [ValidateAntiForgeryToken] ,它给了我预期的结果。

我用Google搜索,并检查了许多解决方案,给出所有这些都是工作。对于我的验证器我用另一种形式在同一个页面,并在防伪标记使用的盐。

示例
为主要形式提交首次防伪标记:


  

@using(Html.BeginForm(创建,注册)){
          @ Html.AntiForgeryToken()
          @ Html.ValidationSummary(真)...}


二防伪标记:

 <表ID =__ AjaxAntiForgeryForm行动=#的方法=后>
    @ Html.AntiForgeryToken(SALT)
< /表及GT;

和在JavaScript我用这个

 <脚本类型=文/ JavaScript的推迟=延迟>
    $(函数(){
        AddAntiForgeryToken =功能(数据){
            数据.__ RequestVerificationToken = $('#__ AjaxAntiForgeryForm输入[名称= __ RequestVerificationToken]')VAL()。
            返回的数据;
        };        如果($(#LOGNAME)长度方式> 0){            $(#LOGNAME)。模糊(函数(){
                。VAR用户= $(#LOGNAME)VAL();
                VAR logValidate =/验证/用户名/;
                // VAR URL = logValidate +用户;
                // VAR令牌= $('#验证输入[名称= __ RequestVerificationToken]')VAL()。
                数据= AddAntiForgeryToken({登录:用户});                $阿贾克斯({
                    键入:POST,
                    数据类型:JSON
                    网址:logValidate,
                    数据:数据,
                    成功:函数(响应){
                        警报(响应);
                    }
                });            });        }
    });
< / SCRIPT>

在我的萤火,我得到这个:

<$p$p><$c$c>log=admin&__RequestVerificationToken=NO8Kds6B2e8bexBjesKlwkSexamsruZc4HeTnFOlYL4Iu6ia%2FyH7qBJcgHusekA50D7TVvYj%2FqB4eZp4VDFlfA6GN5gRz7PB%2ByZ0AxtxW4nT0E%2FvmYwn7Fvo4GzS2ZAhsGLyQC098dfIJaWCSiPcc%2FfD00FqKxjvnqmxhXvnEx2Ye83LbfqA%2F4XTBX8getBeodwUQNkcNi6ZtAJQZ79ySg%3D%3D

如通过,但在Cookie部分我有不同的Cookie不是传递一种:
实际的Cookie:

  ws5Dt2if6Hsah rW2nDly P3cW1smIdp1Vau 0TXOK1w0ctr​​0BCso / nbYu w9blq / QcrXxQLDLAlKBC3Tyhp5ECtK MxF4hhPpzoeByjROUG0NDJfCAlqVVwV5W6lw9ZFp / VBcQmwBCzBM / 36UTBWmWn6pMM2bqnyoqXOK4aUZ4 =

我想这是因为我在一个页面中使用的2防伪标记。但在我的心目中,我应该使用2,因为第一次产生了对提交发生,下一个是需要验证的验证。然而,这是我的猜测,我想我错了,为此我需要你们的帮助。

任何人都可以请解释一下,我应该用两个防伪或者一个事实?

感谢大家提前....


解决方案

最后8小时挣扎给了我一个解决方案。

首先第一件事情,是没有什么危害的页面中使用2防伪标记。和第二,没有必要对饼干与提供令牌相匹配。提供了标记将总是不同,将在服务器进行验证。

如果我们用

防伪标记的无效 [HTTPGET] 行为动词 ..因为在反伪造的验证过程令牌通过检索的Request.Form [__ RequestVerificationToken']从请求价值的验证。 REF:<一href=\"http://blog.stevensanderson.com/2008/09/01/$p$pvent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/\"相对=nofollow>史蒂芬·桑德森的博客:prevent交叉...

解决方案

我的修改器:

  [HttpPost]        [ValidateAntiForgeryToken(盐= @ ApplicationEnvironment.SALT)
//改变地图路线值来接受这个参数。
        公众的ActionResult用户名(ID字符串,字符串__RequestVerificationToken){
        字符串returnParam = __RequestVerificationToken;        尝试{
            如果(ID == NULL || id.Length 3;)
                返回JSON(returnParam,JsonRequestBehavior.AllowGet);            变种构件= Membership.GetUser(ID);            如果(成员== NULL){
                //字符串userPattern = @^([A-ZA-Z])[A-ZA-Z _-] * [\\ w _-] * [\\ S] $ | ^([A-ZA-Z])[0 -9 _-] * [\\ S] $ | ^ [A-ZA-Z] * [\\ S] $;
                字符串userPattern =[A-ZA-Z] [A-ZA-Z0-9 ._] {3,80};
                如果(Regex.IsMatch(ID,userPattern))
                    返回JSON(returnParam,JsonRequestBehavior.AllowGet);
            }        }赶上(例外前){
            CustomErrorHandling.HandleErrorByEmail(例如,验证LOGNAME());
            返回JSON(returnParam,JsonRequestBehavior.AllowGet);
        }
        //发现虚假ê
        返回JSON(returnParam,JsonRequestBehavior.AllowGet);
    }

我在同一页面中第一种形式:

  @using(Html.BeginForm(创建,注册)){    @ Html.AntiForgeryToken(ApplicationEnvironment.SALT)    @ Html.ValidationSummary(真)
    ....
}

我在同一个页面第二种形式:

  ** LT;表ID =验证&GT;
    &LT;! - 有伤害在一个页面中使用2防伪标记 - &GT;
    @ Html.AntiForgeryToken(ApplicationEnvironment.SALT)
    &LT;输入类型=隐藏名称=标识id =ID值=/&GT;
&LT; /形式为GT; **

我的jQuery来解决这件事情:

  $(#LOGNAME)。模糊(函数(){
            。VAR用户= $(#LOGNAME)VAL();
            VAR logValidate =/验证/用户名/;
            $(#验证#ID)VAL(用户)。
            **变种形式= $(#验证),序列化()。 //一种形式是验证防伪标记和数据必须在形式发送非常重要的。**            VAR令牌= $('输入[名称= __ RequestVerificationToken]')VAL()。            $阿贾克斯({
                **类型:POST,//方法必须是POST验证防伪标记,否则将无法正常工作**。
                数据类型:JSON
                网址:logValidate,
                数据:表格,
                成功:函数(响应){
                    警报(响应);
                }
            });
        });

I have been facing serious problem with @Html.AntiForgeryToken() . I have a register controller which had a create view to create/register new members. For that reason I used a @Html.AntiForgeryToken() without using any SALT in my main submit form. Now I would like to validate user name if it is already exist on the database on the blur event of my user name textbox. For this validation I wrote a new controller named 'Validation' and wrote a method with a constant validation SALT:

 [HttpPost]
    [ValidateAntiForgeryToken(Salt = @ApplicationEnvironment.SALT)]
    public ActionResult username(string log) {
        try {
            if (log == null || log.Length < 3)
                return Json(log, JsonRequestBehavior.AllowGet);

            var member = Membership.GetUser(log);

            if (member == null) {
                //string userPattern = @"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$";
                string userPattern = "[A-Za-z][A-Za-z0-9._]{3,80}";
                if (Regex.IsMatch(log, userPattern))
                    return Json(log, JsonRequestBehavior.AllowGet);
            }

        } catch (Exception ex) {
            CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()");
            return Json(log, JsonRequestBehavior.AllowGet);
        }
        //found e false
        return Json(log, JsonRequestBehavior.AllowGet);

    }

Method is working fine . I had checked with the HTTP Get annotation without the [ValidateAntiForgeryToken] and it giving me the expected results.

I had googled and checked many of the given solutions none of these are working. For my validation controller I used another form in the same page and used a SALT in the Anti-forgery token.

Example: First anti-forgery token for the main submit form:

@using (Html.BeginForm("Create", "Register")) { @Html.AntiForgeryToken() @Html.ValidationSummary(true) ... }

Second anti-forgery token:

<form id="__AjaxAntiForgeryForm" action="#" method="post">
    @Html.AntiForgeryToken(SALT)
</form> 

and in the javascript I used this

<script type="text/javascript" defer="defer">
    $(function () {
        AddAntiForgeryToken = function (data) {
            data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
            return data;
        };

        if ($("#LogName").length > 0) {

            $("#LogName").blur(function () {
                var user = $("#LogName").val();
                var logValidate = "/Validation/username/";
                //var URL = logValidate + user;
                //var token = $('#validation input[name=__RequestVerificationToken]').val();
                data = AddAntiForgeryToken({ log: user });

                $.ajax({
                    type: "POST",
                    dataType: "JSON",
                    url: logValidate,
                    data: data,
                    success: function (response) {
                        alert(response);
                    }
                });

            });

        }
    });
</script>

In my firebug I got this :

log=admin&__RequestVerificationToken=NO8Kds6B2e8bexBjesKlwkSexamsruZc4HeTnFOlYL4Iu6ia%2FyH7qBJcgHusekA50D7TVvYj%2FqB4eZp4VDFlfA6GN5gRz7PB%2ByZ0AxtxW4nT0E%2FvmYwn7Fvo4GzS2ZAhsGLyQC098dfIJaWCSiPcc%2FfD00FqKxjvnqmxhXvnEx2Ye83LbfqA%2F4XTBX8getBeodwUQNkcNi6ZtAJQZ79ySg%3D%3D

as passed but in the cookie section I got a different cookie than passing one: Actual Cookie:

ws5Dt2if6Hsah rW2nDly P3cW1smIdp1Vau 0TXOK1w0ctr0BCso/nbYu w9blq/QcrXxQLDLAlKBC3Tyhp5ECtK MxF4hhPpzoeByjROUG0NDJfCAlqVVwV5W6lw9ZFp/VBcQmwBCzBM/36UTBWmWn6pMM2bqnyoqXOK4aUZ4=

I think this is because I used 2 anti-forgery tokens in one page. But in my mind I should use 2 because first one is generating for the submit to occur and next one is need to verify the validation. However, this is my guess and I think I am wrong and for this reason I need help from you guys.

Can anyone please explain the facts that should I use two anti-forgery or one?

Thank you all in advance....

解决方案

Finally 8 hours of struggling gives me a solution.

First things first, yes there is no harm to use 2 anti-forgery tokens in the page. And second there is no need to match the cookies with the providing token. Providing token will be always different and will be verified in the server.

Anti-forgery token does not work if we use [HttpGet] action verbs.. Because in the validation process of anti-forgery the token is validated by retrieving of the Request.Form['__RequestVerificationToken'] value from the request. ref : Steven Sanderson's blog: prevent cross...

Solution :

My modifies controller:

[HttpPost]

        [ValidateAntiForgeryToken(Salt = @ApplicationEnvironment.SALT)]
//change the map route values to accept this parameters.
        public ActionResult username(string id, string __RequestVerificationToken) {
        string returnParam = __RequestVerificationToken;

        try {
            if (id == null || id.Length < 3)
                return Json(returnParam, JsonRequestBehavior.AllowGet);

            var member = Membership.GetUser(id);

            if (member == null) {
                //string userPattern = @"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$";
                string userPattern = "[A-Za-z][A-Za-z0-9._]{3,80}";
                if (Regex.IsMatch(id, userPattern))
                    return Json(returnParam, JsonRequestBehavior.AllowGet);
            }

        } catch (Exception ex) {
            CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()");
            return Json(returnParam, JsonRequestBehavior.AllowGet);
        }
        //found e false
        return Json(returnParam, JsonRequestBehavior.AllowGet);
    }

My first Form in the same page:

@using (Html.BeginForm("Create", "Register")) {

    @Html.AntiForgeryToken(ApplicationEnvironment.SALT)

    @Html.ValidationSummary(true)
    ....
}

My second Form in the same page:

**<form id="validation">
    <!-- there is harm in using 2 anti-forgery tokens in one page-->
    @Html.AntiForgeryToken(ApplicationEnvironment.SALT)
    <input type="hidden" name="id" id="id" value="" />
</form>**

My jQuery to solve this thing:

 $("#LogName").blur(function () {
            var user = $("#LogName").val();
            var logValidate = "/Validation/username/";
            $("#validation #id").val(user);
            **var form = $("#validation").serialize(); // a form is very important to verify anti-forgery token and data must be send in a form.**

            var token = $('input[name=__RequestVerificationToken]').val();

            $.ajax({
                **type: "POST", //method must be POST to validate anti-forgery token or else it won't work.**
                dataType: "JSON",
                url: logValidate,
                data: form,
                success: function (response) {
                    alert(response);
                }
            });
        });

这篇关于是否有可能/右2不同的形式使用多个@ Html.AntiForgeryToken()在一个页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆