2008-09-23 5 views
35

AJAX/JSON 요청에 대한 401 응답 코드의 표준 ASP.NET 처리 (로그인 페이지로 리디렉션)를 비활성화하는 방법은 무엇입니까?ASP.NET MVC에서 json 요청에 대한 401 응답 코드

웹 페이지의 경우에는 괜찮습니다.하지만 AJAX의 경우 로그인 페이지에 대해 302/200의 모양이 좋지 않은 대신 401 오류 코드를 올바르게 입력해야합니다.

업데이트 : - http://haacked.com/archive/2011/10/04/prevent-forms-authentication-login-page-redirect-when-you-donrsquot-want.aspx

답변

18

ASP.NET 런타임은 HttpResponse.StatusCode가 401로 설정되어있는 경우 항상 그러나의 Web.config의 <authentication /> 부분이 발견 될 경우에만 사용자를 리디렉션 수 있도록 개발되고있다.

당신이 필요합니다 인증 섹션을 제거 속성에서 로그인 페이지로의 리디렉션을 구현하지만 큰일이 아니어야한다.

+0

자신의 리디렉션을 구현하는 가장 좋은 방법은 AuthorizeAttribute의 하위 클래스를 만드는 것이고, 권한이 부여되지 않은 경우 결과를 HttpUnauthorizedResult 대신 RedirectResult로 설정합니다. –

+2

예.이 경우 OP는 HTTP 코드 401을 보내고 싶지만 리디렉션하지 않습니다 (JSON과 제대로 작동하기 위해). –

+0

나를 위해 작동 - 비록 속성을 모두 제거하는 대신 설정을 으로 구성했습니다. –

1

사용자 정의 FilterAttributeIAuthorizationFilter 인터페이스를 구현을 만들도록 선택할 수 필 Haack, ASP.NET MVC의 오후에서 몇 가지 솔루션이 있습니다.

요청에 JSON을 반환할지 결정하는 논리를 추가합니다. 그렇다면 사용자가 로그인하지 않은 상태에서 공백 JSON 결과를 반환 할 수 있습니다 (또는 원하는대로 수행 할 수 있습니다). 다른 응답의 경우 사용자를 항상 리디렉션 할 수 있습니다.

클래스의 OnAuthorization을 재정의하면 휠을 재발 명할 필요가 없습니다. 나는 filterContext.Cancel에 해당하는 경우합니다 (filterContext.ResultHttpUnauthorizedResult 클래스의 인스턴스로 설정됩니다 위 절편 언급 한 논리를 추가합니다.

을 필 Haacks 블로그에 "Filters in ASP.NET MVC CodePlex Preview 4"에 대해 자세히 알아보십시오. 또한 최신의 미리보기에 적용됩니다.

+0

그러나 AJAX 요청에 대해 401 응답 상태 코드를 얻을 수 없습니다. Autorization 필터에서 응답을 설정하더라도. 401 응답을 수신하고 로그인 페이지로 리디렉션하는 ASP.NET 인프라가 ASP.NET MVC에 있기 때문에. 사용자가 빈 JSON 결과로 기록되지 않는다는 것을 알려주는 것은 매우 옳지 않습니다 ... – derigel

+0

나는 지금까지 당신이 염두에 두었던 것을 정확히 이해하지 못했습니다. 귀하의 문제를 해결할 새로운 대답을 추가하고 있습니다. –

+1

어떻게 답변을 두 개 게시 할 수 있었습니까? :) – DevDave

2

당신은 또한이 같은과이 프로세스를 중단 할 수의 Global.asax을 사용할 수

protected void Application_PreSendRequestHeaders(object sender, EventArgs e) { 
     if (Response.StatusCode == 401) { 
      Response.Clear(); 
      Response.Redirect(Response.ApplyAppPathModifier("~/Login.aspx")); 
      return; 
     } 
    } 
+1

위의 @troethom의 대답에서 302와 X-Requested-With를 확인한 것을 제외하고는이 작업을 수행했습니다. – Marc

24

을 고전 ASP.NET에서 아약스와의 WebMethod를 호출 할 때 401 HTTP 응답 코드를 얻을. 향후 버전의 ASP.NET MVC에서 변경 될 수 있기를 바랍니다. 지금 나는이 해킹을 사용하고 있습니다 :

protected void Application_EndRequest() 
{ 
    if (Context.Response.StatusCode == 302 && Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest") 
    { 
     Context.Response.Clear(); 
     Context.Response.StatusCode = 401; 
    } 
} 
+0

빠른 속도의 작업이 필요한 경우 정말 좋은 스톱 갭 솔루션입니다. 그렇지 않으면 @troethom 응답을 구현하려고합니다. –

8

폼 인증과 인증되지 않은 Ajax 요청에 대한 401 반환을 원했습니다.

결국 사용자 지정 AuthorizeAttribute를 만들고 컨트롤러 메서드를 장식했습니다.

//web.config (이것은 닷넷 4.5에)

<authentication mode="Forms"> 
</authentication> 

// 컨트롤러

[Authorize(Roles = "Administrator,User"), Response302to401] 
[AcceptVerbs("Get")] 
public async Task<JsonResult> GetDocuments() 
{ 
    string requestUri = User.Identity.Name.ToLower() + "/document"; 
    RequestKeyHttpClient<IEnumerable<DocumentModel>, string> client = 
     new RequestKeyHttpClient<IEnumerable<DocumentModel>, string>(requestUri); 

    var documents = await client.GetManyAsync<IEnumerable<DocumentModel>>(); 

    return Json(documents, JsonRequestBehavior.AllowGet); 
} 

// authorizeAttribute 내가 무엇을 볼 수 없습니다

public class Response302to401 : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      if (filterContext.HttpContext.Request.IsAjaxRequest()) 
      { 
       filterContext.Result = new JsonResult 
       { 
        Data = new { Message = "Your session has died a terrible and gruesome death" }, 
        JsonRequestBehavior = JsonRequestBehavior.AllowGet 
       }; 
       filterContext.HttpContext.Response.StatusCode = 401; 
       filterContext.HttpContext.Response.StatusDescription = "Humans and robots must authenticate"; 
       filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true; 
      } 
     } 
     //base.HandleUnauthorizedRequest(filterContext); 
    } 
} 
+0

사용자가 로그인하지 않았을 때 표준 양식 권한 부여 리디렉션을 사용하고 싶지만 사용자가 관련 권한이없는 경우 사용자 지정 401 리디렉션을 호출하려면 어떻게해야합니까? – DevDave

+0

이 AuthorizeAttribute가없는 메소드에는 일반 양식 리다이렉션이 있습니다. 권한을 확인한 다음 if (! filterContext.IsAuthenticated)의 "else"절을 제공하여이 속성을 확장 한 다음 직접 리디렉션을 설정할 수도 있습니다. –

2

현재의 대답처럼 인증 모드 나 인증 태그를 수정해야합니다.

@TimothyLeeRussell (감사의 말)의 생각에 따라 사용자 지정 Authorize 특성을 만들었습니다 (@TimothyLeeRussell 중 하나의 문제는 생성하는 filterContext.Result를 변경하려고하기 때문에 예외가 throw 됨) HttpException을 제거하고 filterContext.HttpContext.Response.StatusCode = 401 외에도 해당 부분을 제거하면 응답 코드는 항상 200 OK입니다. 그래서 나는 결국 변경 후 응답을 끝내서 문제를 해결했습니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] 
public class BetterAuthorize : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      //Set the response status code to 500 
      filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 
      filterContext.HttpContext.Response.StatusDescription = "Humans and robots must authenticate"; 
      filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true; 

      filterContext.HttpContext.Response.End(); 
     } 
     else 
      base.HandleUnauthorizedRequest(filterContext); 
    } 
} 
당신은 당신의 행동 내에서이 메소드를 호출 할 수 있습니다
+1

SuppressFormsAuthenticationRedirect 속성이 정확히 내가 찾고있는 속성이었습니다. – zeocrash

1

,

HttpContext.Response.End(); 

MSDN에서
public async Task<JsonResult> Return401() 
{ 
    HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 
    HttpContext.Response.End(); 
    return Json("Unauthorized", JsonRequestBehavior.AllowGet); 
} 

: 결국 방법은 웹 서버가 스크립트 처리를 중지하고 현재를 반환됩니다 결과. 파일의 나머지 내용은 처리되지 않습니다.

관련 문제