c# - Authorize on Ajax call -
so have mvc5 project , have ajax call when clicking button, controller called have custom attribute made framework can redirect login page similar non-ajax [authorize]
.
custom attribute:
public class ajaxauthorizeattribute : authorizeattribute { protected override void handleunauthorizedrequest(authorizationcontext context) { if (context.httpcontext.request.isajaxrequest()) { dynamic urlhelper = new urlhelper(context.requestcontext); context.httpcontext.response.statuscode = 403; context.result = new jsonresult { data = new { error = "notauthorized", logonurl = urlhelper.action("registration", "membership") }, jsonrequestbehavior = jsonrequestbehavior.allowget }; } else { base.handleunauthorizedrequest(context); } } }
controller :
[httppost()] [ajaxauthorize()] public void test() { //do }
javascript :
//ajax authorize redirect $(document).ajaxerror(function (e, xhr) { if (xhr.status == 403) { var response = $.parsejson(xhr.responsetext); window.location = response.logonurl; } });
it works fine in localhost, doesn't work when deployed webserver. did checking , turned out xhr.responsetext
in jquery script have different result, here's comparison :
localhost :
{"error":"notauthorized","logonurl":"/membership/registration"} //correct output
webserver :
<!doctype html public "-//w3c//dtd xhtml 1.0 strict//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/> <title>403 - forbidden: access denied.</title> <style type="text/css"> <!-- body{margin:0;font-size:.7em;font-family:verdana, arial, helvetica, sans-serif;background:#eeeeee;} fieldset{padding:0 15px 10px 15px;} h1{font-size:2.4em;margin:0;color:#fff;} h2{font-size:1.7em;margin:0;color:#cc0000;} h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} #header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet ms", verdana, sans-serif;color:#fff; background-color:#555555;} #content{margin:0 0 0 2%;position:relative;} .content-container{background:#fff;width:96%;margin-top:8px;padding:10px;position:relative;} --> </style> </head> <body> <div id="header"><h1>server error</h1></div> <div id="content"> <div class="content-container"><fieldset> <h2>403 - forbidden: access denied.</h2> <h3>you not have permission view directory or page using credentials supplied.</h3> </fieldset></div> </div> </body> </html>
any idea why happening?
method 1 (preferred)
you can set tryskipiiscustomerrors
true responses. this:
protected override void handleunauthorizedrequest(authorizationcontext context) { if (context.httpcontext.request.isajaxrequest()) { dynamic urlhelper = new urlhelper(context.requestcontext); context.httpcontext.response.tryskipiiscustomerrors= true; context.httpcontext.response.statuscode = 403; context.result = new jsonresult { data = new { error = "notauthorized", logonurl = urlhelper.action("registration", "membership") }, jsonrequestbehavior = jsonrequestbehavior.allowget }; } else { base.handleunauthorizedrequest(context); } }
method 2 can stop sending end http status code 403
removing statement handleunauthorizedrequest
.
context.httpcontext.response.statuscode = 403;
this tell client , server this request has succeeded. in case javascript code this,
$(document).ajaxsuccess(function (e, xhr) { var response = $.parsejson(xhr.responsetext); if (typeof(response.error) !== 'undefined') { window.location = response.logonurl; } });