mvc에서 401 (허가되지 않음), 403 (금지됨) 및 500 (내부 서버 오류)을 처리하는 방법. ajax/non-ajax 호출의 경우 및 aspx 양식 인증의 경우.
다양한 캐치되지 않은 예외를 다르게 처리하고 요청이 ajax인지 여부에 따라 다르게 반응하도록 변경할 수 있습니다. auth 부분은 일반 mvc 웹 양식을 리디렉션 - 로그인 페이지로 바꾸지 않고 대신 401 권한을 반환합니다. 그러면 클라이언트 측 js 프레임 워크가 http 상태 401/403에보다 쉽게 대응할 수 있습니다.
// 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>
웹 서비스 API를 요청
추가 경로 : 오류를 처리하는 JQuery와에 대한
// 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 }
);
샘플 클라이언트 측 코드를 (일반 MVC 경로 위에 넣을) :
$.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.");
}
}
});
또는, 모든 인증을 ApplicationHandleErrorAttribute를 통해 수행하고 web.config deny users = "?"를 제거 할 수 있습니다. 하지만 나는 그 거부 사용자가 원하는 mvc 필터링 충돌하지 않는 레거시 aspx 페이지가 = "?".
실제로 내가 동일한 일을하고 있습니다, 공유 컨트롤러 및 승인되지 않은 작업입니다,하지만 여전히 동일한 기본 HTTP 403 페이지 오류가 아닌 내 정의 된 페이지를 수신하고 있습니다 –
매우 유용한 링크 http://stackoverflow.com/questions/2504923/how -to-redirect-authorize-to-loginurl-only-roles-are-un-used –
@SaboorAwan. 나는 행운을 빌어 같은 것을 시도했다. 컨트롤러 메서드는 호출되지 않습니다. 이 답변이나 게시 한 링크로 문제를 해결합니까? – Marco