401이 아닌 로그인 페이지를 반환하는 승인되지 않은 webapi 호출


180

면도기보기에서 호출 된 webapi 메소드가 인증되지 않은 경우 로그인 페이지를 반환하지 않도록 mvc / webapi 프로젝트를 어떻게 구성합니까?

Javascript를 통한 호출을위한 WebApi 컨트롤러가있는 MVC5 애플리케이션입니다.

아래 두 가지 방법

[Route("api/home/LatestProblems")]      
[HttpGet()]
public List<vmLatestProblems> LatestProblems()
{
    // Something here
}

[Route("api/home/myLatestProblems")]
[HttpGet()]
[Authorize(Roles = "Member")]
public List<vmLatestProblems> mylatestproblems()
{
   // Something there
}

다음 각도 코드를 통해 호출됩니다.

angular.module('appWorship').controller('latest', 
    ['$scope', '$http', function ($scope,$http) {         
        var urlBase = baseurl + '/api/home/LatestProblems';
        $http.get(urlBase).success(function (data) {
            $scope.data = data;
        }).error(function (data) {
            console.log(data);
        });
        $http.get(baseurl + '/api/home/mylatestproblems')
          .success(function (data) {
            $scope.data2 = data;
        }).error(function (data) {
            console.log(data);
        });  
    }]
);

그래서 로그인하지 않았고 첫 번째 방법은 성공적으로 데이터를 반환합니다. 두 번째 메소드는 로그인 페이지에 해당하는 데이터를 성공 함수로 리턴합니다. 즉, [Authorize]로 스탬프 처리되고 로그인하지 않은 컨트롤러 작업을 요청한 경우 mvc에 표시되는 내용입니다.

401을 무단으로 반환하여 로그인했는지 여부에 따라 사용자에 대해 다른 데이터를 표시 할 수 있기를 원합니다. 이상적으로 사용자가 로그인 한 경우 해당 회원의 특정 데이터를 반환 할 수 있도록 컨트롤러의 사용자 속성에 액세스 할 수 있기를 원합니다.

업데이트 : 아래 제안 중 더 이상 작동하지 않는 것처럼 보이므로 (Identity 또는 WebAPI 변경) github 에서 원시 예제를 작성 하여 문제를 설명해야합니다.

답변:


78

AuthorizeAttribute 구현에는 두 가지가 있으며 웹 API에 맞는 것을 참조하고 있는지 확인해야합니다. 이 System.Web.Http.AuthorizeAttribute 웹 API의 사용되며, System.Web.Mvc.AuthorizeAttribute 전망 컨트롤러에 사용됩니다. Http.AuthorizeAttribute는 인증이 실패 할 경우 401 오류를 반환하고 Mvc.AuthorizeAttribute는 로그인 페이지로 리디렉션됩니다.

2013 년 11 월 26 일 업데이트

따라서 브록 앨런 이 그의 기사에서 지적한 것처럼 MVC 5에서는 상황이 크게 변화 한 것으로 보입니다 . OWIN 파이프 라인이 대신하여 새로운 동작을 소개합니다. 이제 사용자에게 권한이 부여되지 않으면 HTTP 헤더에 다음 정보와 함께 상태 200이 리턴됩니다.

X-Responded-JSON: {"status":401,"headers":{"location":"http:\/\/localhost:59540\/Account\/Login?ReturnUrl=%2Fapi%2FTestBasic"}}

클라이언트 측의 논리를 변경하여 오류 분기에서 401 상태를 찾는 대신 헤더에서이 정보를 확인하여이를 처리하는 방법을 결정할 수 있습니다.

OnAuthorizationHandleUnauthorizedRequest 메서드 의 응답 상태를 설정하여 사용자 지정 AuthorizeAttribute 에서이 동작을 재정의하려고했습니다 .

actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);

그러나 이것은 효과가 없었습니다. 새 파이프 라인은이 응답을 나중에 가져 와서 이전과 동일한 응답으로 수정해야합니다. 500 오류 상태로 변경되어 HttpException이 발생하지 않았습니다.

Brock Allen의 솔루션을 테스트했으며 jQuery ajax 호출을 사용할 때 작동했습니다. 그것이 당신을 위해 작동하지 않으면 내 추측은 각도를 사용하고 있기 때문입니다. Fiddler로 테스트를 실행하고 헤더에 다음이 있는지 확인하십시오.

X-Requested-With: XMLHttpRequest

그렇지 않으면 이것이 문제입니다. 나는 각도에 익숙하지 않지만 자신의 헤더 값을 삽입 할 수 있다면 이것을 아약스 요청에 추가하면 아마 작동하기 시작할 것이다.


나는 System.web.http.authorizeattribute를 사용하고 있다고 생각합니다. 적어도이 webapicontroller에는 system.web.mvc를 사용하지 않으며 권한 부여 속성의 정의로 이동하면 system.web.http로 이동합니다.
Tim

@ kevin-junghans 님이 완전히 혼란 스럽습니다. shiva에서 위의 예제는 mvc 권한 부여 속성을 사용하여 webapi 작업에 적용해서는 안됩니다 .Brock allen의 예제는 작동하지 않는 것처럼 보입니다. 스텝시 아약스 요청을 생각하지 않습니다.
Tim

1
방금이 대답을 발견했습니다 (스택 오버 플로우가 알림을 보내지 않는다고 생각하십시오). 문제를 설명하기 위해 github 예제를 추가하고 앵글 헤더에 수정 사항을 추가했습니다. 감사. 그러나 권한 부여 속성에 확인할 수있는 속성이 없거나 언급 한 원래 기능이 더 이상 작동하지 않는 것은 옳지 않은 것 같습니다.
Tim

3
사용 POSTMAN 및 헤더 PARAM X가-요청-으로 : XMLHttpRequest의 나를 위해 작동합니다 ... 감사합니다
chemitaxis

그렇다면 순수 웹 API 프로젝트가 되려는 목표가 있다면 어떨까요? 다른 사람이 설정 한 프로젝트에서 작업 중이며 권한 부여가 여기에 설명 된대로 리디렉션되지만 다른 API 프로젝트가 있습니다. API 앱이 아닌 MVC 앱이라고 생각하는 무언가가 있어야하지만 그것을 부패시킬 수있는 것을 찾을 수 없습니다.
Derek Greer

123

Brock Allen은 쿠키 인증 및 OWIN을 사용할 때 ajax 호출에 대해 401을 반환하는 방법에 대한 멋진 블로그 게시물을 보유하고 있습니다. http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

이것을 Startup.Auth.cs 파일의 ConfigureAuth 메소드에 넣습니다.

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
  AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
  LoginPath = new PathString("/Account/Login"),
  Provider = new CookieAuthenticationProvider
  {
    OnApplyRedirect = ctx =>
    {
      if (!IsAjaxRequest(ctx.Request))
      {
        ctx.Response.Redirect(ctx.RedirectUri);
      }
    }
  }
});

private static bool IsAjaxRequest(IOwinRequest request)
{
  IReadableStringCollection query = request.Query;
  if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
  {
     return true;
  }
  IHeaderDictionary headers = request.Headers;
  return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
}

68
이에 대한 변형 : 예를 들어 모든 웹 API 호출이 특정 경로를 통과하는 /api경우 경로를 사용하여 경로 재 지정 여부를 결정할 수 있습니다. JSON과 같은 다른 형식을 사용하는 클라이언트가있는 경우 특히 유용합니다. 통화를 IsAjaxRequest로 교체하십시오 if (!context.Request.Path.StartsWithSegments(new PathString("/api"))).
Edward Brey

파티에 늦었지만이 방법은 저에게 효과적이며 더 "정확한"것 같습니다.
Stephen Collins

심지어 파티에 늦었지만, 이것은 매우 유용하다는 것이 입증되었습니다 ... 디폴트 생성 된 기본 코드가 디버깅하기가 너무 어려워 어려운 방식으로 그렇게 잘못했다고 생각합니다.
Nick

WebApi 솔루션을 사용하고 있다면 Manik의 답변은 여기에서 투표가 많은 의견에 대한 좋은 대안입니다.
Dunc

5
C # 6을 사용하는 IsAjaxRequest의 작은 버전은 다음과 같습니다. private static bool IsAjaxRequest(IOwinRequest request) { return request.Query?["X-Requested-With"] == "XMLHttpRequest" || request.Headers?["X-Requested-With"] == "XMLHttpRequest"; }
Peter Örneholm

85

asp.net MVC 웹 사이트에 asp.net WebApi를 추가하는 경우 일부 요청에 대해 무단으로 응답하려고합니다. 그러나 ASP.NET 인프라가 작동하고 응답 상태 코드를 HttpStatusCode로 설정하려고하면 302가 로그인 페이지로 리디렉션됩니다.

여기에 asp.net ID 및 owin 기반 인증을 사용하는 경우 해당 문제를 해결하는 데 도움이되는 코드가 있습니다.

public void ConfigureAuth(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider()
        {
            OnApplyRedirect = ctx =>
            {
                if (!IsApiRequest(ctx.Request))
                {
                    ctx.Response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });

    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}


private static bool IsApiRequest(IOwinRequest request)
{
    string apiPath = VirtualPathUtility.ToAbsolute("~/api/");
    return request.Uri.LocalPath.StartsWith(apiPath);
}

1
요청이 text / html 또는 application / xhtml을 응답으로 수락하는지 확인하기 위해 판별자를 변경했습니다. 요청이 "자동화 된"클라이언트 요청 (예 : ajax 요청)이라고 가정하지 않는 경우
L.Trabacchin

4
나는이 접근법도 선호합니다. 내가 추가 한 것은 LocalPath .ToLower ()를 "/ API"또는 다른 것을 요청하는 경우 변환하는 것입니다.
FirstDivision

1
고마워 그것은 나의 하루를 구했다. :)
Kumar를

누구든지 이것으로 운이 있습니까? CookieAuthenticationOptions에는 더 이상 aspnet core 1.1의 Provider 속성이 없습니다.
Jeremy

27

OWIN이 WebApi의 401 응답을 항상 로그인 페이지로 리디렉션 할 때와 같은 상황이 발생했습니다. 우리의 웹 API는 Angular의 ajax 호출뿐만 아니라 Mobile, Win Form 호출도 지원합니다. 따라서 요청이 아약스 요청인지 확인하는 솔루션은 실제로 우리의 경우에 따라 정렬되지 않습니다.

Suppress-RedirectwebApi에서 응답이 오는 경우 새로운 헤더 응답을 삽입하는 또 다른 방법을 선택 했습니다. 구현은 핸들러에 있습니다.

public class SuppressRedirectHandler : DelegatingHandler
{
    /// <summary>
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken).ContinueWith(task =>
        {
            var response = task.Result;
            response.Headers.Add("Suppress-Redirect", "True");
            return response;
        }, cancellationToken);
    }
}

그리고이 핸들러를 글로벌 레벨의 WebApi에 등록하십시오.

config.MessageHandlers.Add(new SuppressRedirectHandler());

따라서 OWIN 시작시 응답 헤더에 다음이 있는지 여부를 확인할 수 있습니다 Suppress-Redirect.

public void Configuration(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationMode = AuthenticationMode.Active,
        AuthenticationType = DefaultApplicationTypes.ApplicationCookie,
        ExpireTimeSpan = TimeSpan.FromMinutes(48),

        LoginPath = new PathString("/NewAccount/LogOn"),

        Provider = new CookieAuthenticationProvider()
        {
            OnApplyRedirect = ctx =>
            {
                var response = ctx.Response;
                if (!IsApiResponse(ctx.Response))
                {
                    response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });
}

private static bool IsApiResponse(IOwinResponse response)
{
    var responseHeader = response.Headers;

    if (responseHeader == null) 
        return false;

    if (!responseHeader.ContainsKey("Suppress-Redirect"))
        return false;

    if (!bool.TryParse(responseHeader["Suppress-Redirect"], out bool suppressRedirect))
        return false;

    return suppressRedirect;
}

감사합니다 ! 우리의 API는 Xamarin / Android를 제외한 모든 플랫폼에서 작동했습니다. 이 솔루션을 사용할 것입니다
Jurion

17

이전 버전의 ASP.NET에서는 많은 작업수행해야했습니다. 이 작업 하기 위해 했습니다.

좋은 소식은 ASP.NET 4.5를 사용하고 있기 때문입니다. 새로운 HttpResponse.SuppressFormsAuthenticationRedirect를 사용하여 양식 인증 리디렉션을 비활성화 할 수 있습니다. 속성을 .

에서 Global.asax:

protected void Application_EndRequest(Object sender, EventArgs e)
{
        HttpApplication context = (HttpApplication)sender;
        context.Response.SuppressFormsAuthenticationRedirect = true;
}

편집 : 이 기사를 살펴볼 수도 있습니다. 보다 세련되게하는 Sergey Zwezdin 를 .

관련 코드 스 니펫 및 작성자 설명이 아래에 붙여졌습니다. 코드 및 내레이션의 원저자-Sergey Zwezdin .

먼저 – 현재 HTTP 요청이 AJAX 요청인지 확인합니다. 그렇다면 HTTP 401을 HTTP 302로 바꾸지 말아야합니다.

public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;
        var request = httpContext.Request;
        var response = httpContext.Response;

        if (request.IsAjaxRequest())
            response.SuppressFormsAuthenticationRedirect = true;

        base.HandleUnauthorizedRequest(filterContext);
    }
}

둘째 – 조건을 추가합시다 : 사용자가 인증되면 HTTP 403을 보냅니다. 그렇지 않으면 HTTP 401입니다.

public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;
        var request = httpContext.Request;
        var response = httpContext.Response;
        var user = httpContext.User;

        if (request.IsAjaxRequest())
        {
            if (user.Identity.IsAuthenticated == false)
                response.StatusCode = (int)HttpStatusCode.Unauthorized;
            else
                response.StatusCode = (int)HttpStatusCode.Forbidden;

            response.SuppressFormsAuthenticationRedirect = true;
            response.End();
        }

        base.HandleUnauthorizedRequest(filterContext);
    }
}

잘 했어. 이제 표준 AuthorizeAttribute의 모든 사용을이 새로운 필터로 바꿔야합니다. 코드를 간직한 사람에게는 적용되지 않을 수 있습니다. 그러나 나는 다른 방법을 모른다. 당신이 있다면, 코멘트로 가자.

마지막으로, 클라이언트 측에서 HTTP 401/403 처리를 추가하기 위해해야 ​​할 일. 코드 중복을 피하기 위해 jQuery에서 ajaxError를 사용할 수 있습니다.

$(document).ajaxError(function (e, xhr) {
    if (xhr.status == 401)
        window.location = "/Account/Login";
    else if (xhr.status == 403)
        alert("You have no enough permissions to request this resource.");
});

결과 -

  • 사용자가 인증되지 않은 경우 AJAX 호출 후 로그인 페이지로 리디렉션됩니다.
  • 사용자가 인증되었지만 충분한 권한이없는 경우 사용자에게 친숙한 오류 메시지가 표시됩니다.
  • 사용자가 인증되고 충분한 권한이있는 경우 오류가 없으며 평소와 같이 HTTP 요청이 진행됩니다.

저는 mvc를 통해 auth에 새로운 ID 프레임 워크를 사용하고 있습니다. 이 설정으로 인해 mvc 로그인 및 webapi 호출이 작동하지 않습니까?
Tim

5
이 예제를 확인하면 사용중인 권한 부여 속성이 WebApi 버전이 아닌 MVC 버전 인 것으로 보입니다. 그러나 webapi 버전에는 양식 인증을 억제하는 옵션이 없습니다.
Tim

내 요청에 IsAjaxRequest 메소드가 없습니다.
Tim

1
Tim은 IsAjaxRequest : brockallen.com/2013/10/27/…에 대해 살펴보십시오 . 헤더를 편집하지 않고 AngularJ를 사용하는 경우 "XMLHttpRequest"가없고 추가하거나 다른 것을 확인하십시오.
Tim

10

프로젝트 Web API내에서 실행중인 경우 메소드 에 적용 할 MVC사용자 정의 AuthorizeAttribute를 작성 해야 API합니다. 내부에서 IsAuthorized override다음 HttpContext과 같이 리디렉션을 방지하기 위해 전류를 가져와야합니다 .

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (string.IsNullOrWhiteSpace(Thread.CurrentPrincipal.Identity.Name))
        {
            var response = HttpContext.Current.Response;
            response.SuppressFormsAuthenticationRedirect = true;
            response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden;
            response.End();
        }

        return base.IsAuthorized(actionContext);
    }

8

Azure Active Directory 통합을 직접 사용하면 CookieAuthentication미들웨어를 사용하는 접근 방식이 효과 가 없었습니다. 나는 다음을 수행해야했다.

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
        ...
        Notifications = new OpenIdConnectAuthenticationNotifications
        {   
            ...         
            RedirectToIdentityProvider = async context =>
            {
                if (!context.Request.Accept.Contains("html"))
                {
                    context.HandleResponse();
                }
            },
            ...
        }
    });

요청이 브라우저 자체 (예 : AJAX 호출이 아닌)에서 온 경우 Accept 헤더에는 문자열이 포함됩니다. html 어딘가에 . 클라이언트가 HTML을 수락 할 때만 리디렉션이 유용한 것으로 간주합니다.

내 클라이언트 응용 프로그램은 401을 처리하여 사용자에게 앱에 더 이상 액세스 권한이 없으며 다시 로그인하기 위해 다시로드해야 함을 알려줍니다.


이것은 관련 질문에 제안 된 솔루션과 매우 유사합니다 : stackoverflow.com/questions/34997674/…
Guillaume LaHaye

6

또한 WebApi (OWIN 사용)가있는 MVC5 응용 프로그램 (System.Web)이 있었고 WebApi의 401 응답이 302 응답으로 변경되는 것을 막고 싶었습니다.

나를 위해 일한 것은 다음과 같이 WebApi AuthorizeAttribute의 사용자 정의 버전을 작성하는 것이 었습니다.

public class MyAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        base.HandleUnauthorizedRequest(actionContext);
        HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true;
    }
}

표준 WebApi AuthorizeAttribute 대신 사용하십시오. 표준 MVC AuthorizeAttribute를 사용하여 MVC 동작을 변경하지 않았습니다.


작동하지만 이제는 클라이언트가 401 대신 -1 상태를 수신한다는 문제가 있습니다.
Sebastián Rojas

@ SebastiánRojas 그 원인이 무엇인지 잘 모르겠습니다. SuppressFormsAuthenticationRedirect 플래그를 설정 하면 기존 401이 반환됩니다.
Jono Job

3

다음 NeGet 패키지를 설치하십시오.

설치 패키지 Microsoft.AspNet.WebApi.Owin

WebApiConfig 파일에 다음 코드를 작성하십시오.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        //Web API configuration and services
        //Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
    }
}

내가해야 할 일은이 필터를 추가하는 것이었고 config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));그렇지 않은 경우 User.Identity.IsAuthenticated항상 작동 합니다.false
Ricardo Saracino

1

Content-Type == application / json을 잡으려면 해당 코드를 사용할 수 있습니다.

private static bool IsAjaxRequest(IOwinRequest request)
    {
        IReadableStringCollection queryXML = request.Query;
        if ((queryXML != null) && (queryXML["X-Requested-With"] == "XMLHttpRequest"))
        {
            return true;
        }

        IReadableStringCollection queryJSON = request.Query;
        if ((queryJSON != null) && (queryJSON["Content-Type"] == "application/json"))
        {
            return true;
        }

        IHeaderDictionary headersXML = request.Headers;
        var isAjax = ((headersXML != null) && (headersXML["X-Requested-With"] == "XMLHttpRequest"));

        IHeaderDictionary headers = request.Headers;
        var isJson = ((headers != null) && (headers["Content-Type"] == "application/json"));

        return isAjax || isJson;

    }

문안 인사!!


1

OnAuthorization / HandleUnauthorizedRequest 메서드에서 작동하는 상태 코드와 텍스트 응답을 모두 얻는 데 어려움을 겪고있었습니다. 이것은 나에게 가장 좋은 해결책으로 판명되었습니다.

    actionContext.Response = new HttpResponseMessage()
    {
        StatusCode = HttpStatusCode.Forbidden,
        Content = new StringContent(unauthorizedMessage)
    };

1

로그인 페이지로의 리디렉션을 피하려고 많은 노력을 기울인 후에 실제로 이것이 Authorize 속성에 매우 적합하다는 것을 깨달았습니다. 가서 가서 허가를 받는다는 말입니다. 승인되지 않은 Api 통화 대신 해커가 될 정보를 공개하지 않고 싶었습니다. 이 목표는 Authorize에서 파생 된 새로운 속성을 추가하여 404 오류로 내용을 숨기는 대신 직접 달성하기가 더 쉬웠습니다.

public class HideFromAnonymousUsersAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
         actionContext.Response = ActionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, "Access Restricted");
    }
}

1

요청이 승인되지 않은 경우 MVC와 WebAPI를 혼합하면 WebAPI 요청에서도 로그인 페이지로 리디렉션됩니다. 이를 위해 아래 코드를 추가하여 모바일 애플리케이션에 응답을 보낼 수 있습니다.

protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
    var httpContext = HttpContext.Current;
    if (httpContext == null)
    {
        base.HandleUnauthorizedRequest(actionContext);
        return;
    }

    actionContext.Response = httpContext.User.Identity.IsAuthenticated == false ?
        actionContext.Request.CreateErrorResponse(
      System.Net.HttpStatusCode.Unauthorized, "Unauthorized") :
       actionContext.Request.CreateErrorResponse(
      System.Net.HttpStatusCode.Forbidden, "Forbidden");

    httpContext.Response.SuppressFormsAuthenticationRedirect = true;
    httpContext.Response.End();
}

0

고마워요!

제 경우에는 cuongle & Shiva 의 답변을 결합하여 다음과 같은 것을 얻었습니다.

API 예외에 대한 컨트롤러의 OnException () 핸들러에서 :

filterContext.ExceptionHandled = true;
//...
var response = filterContext.HttpContext.Response;
response.Headers.Add("Suppress-Redirect", "true");
response.SuppressFormsAuthenticationRedirect = true;

앱 시작 구성 코드에서 :

app.UseCookieAuthentication(new CookieAuthenticationOptions {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider {
            OnValidateIdentity = ctx => {
                return validateFn.Invoke(ctx);
            },
            OnApplyRedirect = ctx =>
            {
                bool enableRedir = true;
                if (ctx.Response != null)
                {
                    string respType = ctx.Response.ContentType;
                    string suppress = ctx.Response.Headers["Suppress-Redirect"];
                    if (respType != null)
                    {
                        Regex rx = new Regex("^application\\/json(;(.*))?$",
                            RegexOptions.IgnoreCase);
                        if (rx.IsMatch(respType))
                        {
                            enableRedir = false;
                        }  
                    }
                    if ((!String.IsNullOrEmpty(suppress)) && (Boolean.Parse(suppress)))
                    {
                        enableRedir = false;
                    }
                }
                if (enableRedir)
                {
                    ctx.Response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });

-1

Dot Net Framework 4.5.2가 포함 된 MVC 5에서 "Accept"헤더 아래에 "application / json, plaint text .."가 표시됩니다. 다음과 같이 사용하면 좋습니다.

isJson = headers["Content-Type"] == "application/json" || headers["Accept"].IndexOf("application/json", System.StringComparison.CurrentCultureIgnoreCase) >= 0;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.