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
Post a Comment