Cách xử lý 401 (Không được phép), 403 (Bị cấm) và 500 (Lỗi máy chủ nội bộ) trong mvc. Đối với các cuộc gọi ajax/non-ajax và dưới hình thức xác thực aspx.
Nó có thể được thay đổi để xử lý các trường hợp ngoại lệ chưa được nhận khác nhau và phản ứng khác nhau cho dù yêu cầu là ajax hay không. Phần auth cho phép nó bỏ qua bất kỳ biểu mẫu web chuyển hướng-to-login-trang mvc thông thường nào và thay vào đó trả về 401 trái phép - thì khung công tác js phía máy khách của bạn có thể phản ứng với trạng thái http 401403 dễ dàng hơn.
// FilterConfig.cs:
filters.Add(new ApplicationAuthorizeAttribute());
filters.Add(new ApplicationHandleErrorAttribute());
public class ApplicationAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// Note: To reach here, a Web.config path-specific rule 'allow users="?"' is needed (otherwise it redirects to login)
var httpContext = filterContext.HttpContext;
var request = httpContext.Request;
var response = httpContext.Response;
if (request.IsAjaxRequest())
{
response.SuppressFormsAuthenticationRedirect = true;
response.TrySkipIisCustomErrors = true;
}
filterContext.Result = new HttpUnauthorizedResult();
}
}
public class ApplicationHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext context)
{
var exception = context.Exception is AggregateException
? ((AggregateException)context.Exception).InnerExceptions.First()
: context.Exception;
var request = context.HttpContext.Request;
var response = context.HttpContext.Response;
var isAjax = request.IsAjaxRequest();
if (exception is MyCustomPermissionDeniedException)
{
filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);
response.TrySkipIisCustomErrors = isAjax;
filterContext.ExceptionHandled = true;
return;
}
#if DEBUG
if (!isAjax)
{
// Show default aspx yellow error page for developers
return;
}
#endif
var requestUri = request.Url == null ? "" : request.Url.AbsoluteUri;
MyCustomerLogger.Log(exception, requestUri);
response.Clear();
response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
#if DEBUG
var errorMessage = exception.Message;
#else
var errorMessage = "An error occurred, please try again or contact the administrator.";
#endif
response.Write(isAjax
? JsonConvert.SerializeObject(new {Message = errorMessage})
: errorMessage);
response.End();
response.TrySkipIisCustomErrors = true;
context.ExceptionHandled = true;
}
}
Web.config:
<system.webServer>
<authentication mode="Forms">
<forms name=".MYAUTHCOOKIE" protection="All" loginUrl="/Account/Login" timeout="18000" slidingExpiration="true" enableCrossAppRedirects="false" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.webServer>
<!-- ajax api security done via ApplicationAuthorizeAttribute -->
<location path="api">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
tuyến đường bổ sung cho các yêu cầu api dịch vụ web: (đặt trên tuyến đường thường xuyên MVC)
// This route has special ajax authentication handling (no redirect to login page)
routes.MapRoute(
name: "DefaultApi",
url: "api/{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional }
);
mẫu client side code cho jquery để xử lý các lỗi :
$.ajaxSetup({
complete: function onRequestCompleted(xhr, textStatus) {
if (xhr.readyState == 4 && xhr.status == 401) {
// Not needed with smart status: && xhr.responseText.substring(0, 150).indexOf("<title>Log in") != -1
//location.href = "/Account/Login";
alert("Your session has timed out.");
}
}
});
Ngoài ra, bạn có thể làm cho tất cả các auth đi qua ApplicationHandleErrorAttribute, và thoát khỏi web.config deny users = "?". Nhưng tôi có một trang aspx di sản mà không nhấn lọc mvc vì vậy tôi muốn từ chối người dùng = "?".
Nguồn
2015-05-27 17:24:03
thực sự tôi đang làm như vậy, được chia sẻ là bộ điều khiển và trái phép là hành động, nhưng tôi vẫn nhận được lỗi mặc định http 403 trang, không phải trang xác định của tôi –
liên kết rất hữu ích http://stackoverflow.com/questions/2504923/how -to-redirect-authorise-to-loginurl-only-khi-vai trò-không-được sử dụng –
@SaboorAwan. Tôi đã thử cùng với không may mắn. Phương thức điều khiển không bao giờ được gọi. Bạn có giải quyết được vấn đề với câu trả lời này hoặc với liên kết bạn đã đăng không? – Marco