c# - Get the raw values (not html) from AntiForgeryToken() -


this beautiful abstraction lets place @html.antiforgerytoken() in cshtml file magically expanded like;

<input name="__requestverificationtoken" type="hidden" value="jjmhm5kjq/qjsyc4sgifqwwx/wmadmnveghzxxub07bwol84drmqze6k9irvyfsj5vsyqeuixgl4dw4nhsotlwflgytyeczlvrgzbtonxj9m3gvpguv7z6s2ih/klub78gn7fl4gj7kxg62meogczw175evwtmkkj0xrtefd5kcvvyimhny8mt2l+qhltsgl87c9dii42avouuq2gtvfpg==" /> 

by mvc before page served. page has javascript making ajax calls don't include token though it's been added form. getting expected [httpantiforgeryexception]: required anti-forgery token not supplied or invalid. because don't have token. i'm aware could parse value out of dom shouldn't have to. there other ways of accessing/getting value? clear, mean i'd overload of method returns value string or kind of object has name , value both.

to provide bit more context form , relevant js looks little this;

<form action="/settings" method="post"><input name="__requestverificationtoken" type="hidden" value="jjmhm5kjq/qjsyc4sgifqwwx/wmadmnveghzxxub07bwol84drmqze6k9irvyfsj5vsyqeuixgl4dw4nhsotlwflgytyeczlvrgzbtonxj9m3gvpguv7z6s2ih/klub78gn7fl4gj7kxg62meogczw175evwtmkkj0xrtefd5kcvvyimhny8mt2l+qhltsgl87c9dii42avouuq2gtvfpg==" />    <fieldset>         <h3>user settings</h3>         <ul>             <li>             label for="password">password</label>                 <a href="#" id="change_password" class="changepasswordbutton">edit</a>                 <div id="password_section" class="inlineedit">                     <div>                         <span for="existing_password">current password</span> <input autocomplete="off" class="required" id="existing_password" name="existing_password" type="password" />                     </div>                     <div>                         <span for="new_password">new password</span> <input autocomplete="off" class="required" id="new_password" name="new_password" type="password" />                         <span id="password_strength" />                     </div>                     <div>                         <span for="confirm_password">confirm password</span> <input autocomplete="off" class="required" id="confirm_password" name="confirm_password" type="password" />                     </div>                     <div class="inlinesave">                         <input type="button" value="change" onclick="onpostchangepassword();"/>                         <a href="#" id="cancel_password" class="cancel">cancel</a>                     </div>                 </div>             </li>     // bunch more of these call own onpostchangesetting method 

onpostchangepassword() input validation then;

 if(validpwd && validnewpwd && validconfirmpwd && current_pwd != new_pwd){                         // post password change                         var currentajaxrequest = $.ajax({                             type: "post",                             url: "/settings/preferences/changepassword",                             cache: false,                             data: {password: $('#new_password').val(), current: $('#existing_password').val(),confirm: $('#confirm_password').val()},                             success: password_success,                             error: password_error,                             datatype: "json"                         });                         return true;                   } 

which ideally (since verbatim in cshtml file) modified this;

data: {password: $('#new_password').val(), current: $('#existing_password').val(),confirm: $('#confirm_password').val(), __requestverificationtoken:@html.antiforgeryvalue() } 

tl;dr there way interact antiforgeytoken before it's turned string of html?

you can use code (in example _layout.cshtml) add antiforgery header ajax post requests, or adapt specific request. (code assumes using jquery)

@functions{     private static string tokenheadervalue()     {         string cookietoken, formtoken;         antiforgery.gettokens(null, out cookietoken, out formtoken);         return cookietoken + ":" + formtoken;     } }  <script type="text/javascript">     $(document).ajaxsend(function (event, jqxhr, settings) {         if (settings.type == "post") {                jqxhr.setrequestheader('@validatehttpantiforgerytokenattribute.requestverificationtokenname',                                    '@tokenheadervalue()');         }     }); </script> 

on server side these ajax calls, want call the overload of antiforgery.validate takes cookie , form token, enable adding attribute action methods called via ajax (explicitly, or parent controller, or via filter)

[attributeusage(attributetargets.method | attributetargets.class,                 allowmultiple = false, inherited = true)] public sealed class validatehttpantiforgerytokenattribute                                   : filterattribute, iauthorizationfilter  {     public const string requestverificationtokenname = "requestverificationtoken";      public void onauthorization(authorizationcontext filtercontext)     {         if (filtercontext.httpcontext.request.isajaxrequest())         {             validaterequestheader(filtercontext.httpcontext.request);         }         else         {             antiforgery.validate();         }     }      private static void validaterequestheader(httprequestbase request)     {         string cookietoken = string.empty;         string formtoken = string.empty;          var tokenvalue = request.headers[requestverificationtokenname];          if (string.isnullorempty(tokenvalue) == false)         {             string[] tokens = tokenvalue.split(':');              if (tokens.length == 2)             {                 cookietoken = tokens[0].trim();                 formtoken = tokens[1].trim();             }         }          antiforgery.validate(cookietoken, formtoken);     } 

Comments

Popular posts from this blog

python - No exponential form of the z-axis in matplotlib-3D-plots -

php - Best Light server (Linux + Web server + Database) for Raspberry Pi -

c# - "Newtonsoft.Json.JsonSerializationException unable to find constructor to use for types" error when deserializing class -