2011-08-11 6 views
14

나는 설정 403 오류 페이지가

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsAuthenticated) 
     { 
      filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult(403); 
     } 
     else 
     { 
      base.HandleUnauthorizedRequest(filterContext); 
     } 
    } 
} 

지금의 Web.config에 내가 403 오류 페이지

<customErrors defaultRedirect="/Shared/Error" mode="On"> 
    <error statusCode="403" redirect="/Shared/UnAuthorize" /> 
</customErrors> 

를 구성하지만 브라우저가 아직도 날이 기본이다

사용자 정의 인증을 수행하는 클래스를 오버라이드 (override) 오류 페이지 403, 여기에 무엇을 놓치고 무엇입니까

답변

11

그냥 작은 힌트/메모를 최대 B. 대답 외에 :

나는 사용자 정의 오류를 사용하고 언제는 ErrorsController을하고 UnAuthorize ActionResult 및

<error statusCode="403" redirect="/Errors/UnAuthorize" /> 

나는 추가 정보를 추가하거나, 예를 들어, 내 컨트롤러에서 다른 작업을 할 수있는이 방법 :

    다음을 수행
  • 누군가가 인증 된 영역에 액세스하려고 시도한 데이터베이스 로깅과 같습니다.
  • 오류 계산.
  • 아마도 관리자 정보를 보내는 데 사용할 수있는 버그 또는 보고서 양식 일 수 있습니다.
  • ...

당신이 무슨 일이 일어나고 있는지에 좀 더 제어 할 수 있습니다이 방법.

+0

실제로 내가 동일한 일을하고 있습니다, 공유 컨트롤러 및 승인되지 않은 작업입니다,하지만 여전히 동일한 기본 HTTP 403 페이지 오류가 아닌 내 정의 된 페이지를 수신하고 있습니다 –

+1

매우 유용한 링크 http://stackoverflow.com/questions/2504923/how -to-redirect-authorize-to-loginurl-only-roles-are-un-used –

+2

@SaboorAwan. 나는 행운을 빌어 같은 것을 시도했다. 컨트롤러 메서드는 호출되지 않습니다. 이 답변이나 게시 한 링크로 문제를 해결합니까? – Marco

-1

내게는 HttpStatusCodeResult (403) 잘못 경우 분기 것 같습니다. 제 생각에는 코드는 다음과 같아야합니다

+1

인증 할 때 인증 요구 사항을 우회하는 것으로 테스트 할 수 있습니다. – JustinStolle

3

또는 당신이 사용하는 대신,이 대체 솔루션을 수행 할 수 있습니다

filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult(403); 

당신은 그것을 변경할 수 있습니다

if (filterContext.HttpContext.Request.IsAuthenticated) 
     {    
      throw new UnauthorizedAccessException(); 
     } 

그리고 재정의 방법 OnException (ExceptionContext filterContext) 당신의 컨트롤러/BaseController

protected override void OnException(ExceptionContext filterContext) 
    { 
     if (filterContext.ExceptionHandled) 
     { 
      return; 
     } 

     if (filterContext.Exception.GetType() == typeof(UnauthorizedAccessException)) 
     { 
      filterContext.Result = new ViewResult 
      { 
       ViewName = "~/Views/Error/NotAuthorized.cshtml" 
      }; 
      filterContext.ExceptionHandled = true; 
      return; 
     } 

     base.OnException(filterContext); 
    } 
6

내가 쓴 시간과 똑같은 문제가있었습니다. 사용자 정의 AuthorizeAttribute. web.config에 "customErrors"태그를 추가하면 403에 대한 사용자 정의 오류 페이지가 표시되지 않습니다. 이것은 내가 그것을 해결있어하는 방법입니다

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsAuthenticated) 
     { 
      filterContext.Result = new RedirectToRouteResult(
       new RouteValueDictionary(
        new 
         { 
          controller = "Error", 
          action = "Unauthorised" 
         }) 
       ); 

     } 
     else 
     { 
      base.HandleUnauthorizedRequest(filterContext); 
     } 
    } 
} 

내가 대신 403 HttpStatusCode를 할당하는, filterContext.Result에 표시하고 싶은 경로를 지정.

8

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만 같은 문제가있는 사람에게 게시하고 있습니다. 나처럼, 나는 똑같은 문제를 안고 그것을 풀었다. web.config에서 customErrors 요소를 트리거하려면 아래에서 시도하십시오.

protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext) 
{ 
    throw new HttpException(403, "Forbidden"); 
} 
+0

다른 솔루션보다 완벽하고 쉽게 작동합니다. – Guillaume

+2

어디 넣을까요? 추가하는 것이 좋을까요. 특정 지역 일 수 있습니까? – CularBytes

+0

@RageCompex 사용자 지정 특성 클래스에 넣을 수 있습니다. 그리고 '지역 특유의'에 대해 더 자세히 설명해 줄 수 있습니까? – user3110409

0

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 페이지가 = "?".

+0

실제로 F12 (ms 심볼 서버를 resharper 디 컴파일하면) : ControllerActionInvoker, HandleErrorAttribute, AuthorizeAttribute 수 있어야합니다. 이것은 매우 계몽적인 독서입니다. ControllerActionInvoker는 4 가지 필터 유형 각각을 다르게 사용합니다. (예 : 인증, 조치, 결과, 예외) 예를 들어 컨트롤러로 이동하여 기본 클래스 "Controller"에서 F12를 누르고 "IAuthorizationFilter"에서 F12를 누르고 OnAuthorization에서 Shift-F12를 누릅니다. –