programing

ASP.NET MVC - 로그인 페이지에서 무단 오류를 표시하는 방법은 무엇입니까?

closeapi 2023. 7. 30. 17:50
반응형

ASP.NET MVC - 로그인 페이지에서 무단 오류를 표시하는 방법은 무엇입니까?

내 ASP에서.NET MVC 앱, 나는 대부분의 컨트롤러를 장식했습니다.

[Authorize(Roles="SomeGroup")]

사용자에게 액세스 권한이 없는 경우 사용자는 "~/로그인"(내 계정 컨트롤러의 로그인 작업)으로 전송됩니다.

인증되지 않아 사용자가 로그인 페이지에 도달했는지 확인하여 적절한 오류를 표시하려면 어떻게 해야 합니까?

업데이트(2015년 6월): @daniel-lidström은 응답을 사용해서는 안 된다고 올바르게 지적했습니다.ASP에서 리디렉션합니다.NET MVC 응용 프로그램.이유에 대한 자세한 내용은 응답 링크를 참조하십시오.리디렉션 및 ASP.NET MVC – 혼합하지 마십시오.

업데이트(2014년 9월):언제 HandleUnauthorizedRequest가 AuthorizedAttribute에 추가되었는지는 잘 모르겠지만, 어느 쪽이든 AuthorizedRedirect 코드를 더 작고 간단한 것으로 다듬을 수 있었습니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeRedirect : AuthorizeAttribute
{
    public string RedirectUrl = "~/Error/Unauthorized";

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectResult(RedirectUrl);
        }
    }
}

아래의 원본 답변(아직 완전히 작동함)

권한 부여 파이프라인이 어떻게 작동하는지에 대한 통찰력을 제공하기 때문에 이 답변을 여기에 남겼습니다.

아직 여기에 도착한 사람들을 위해, 나는 사용자가 로그인했지만 권한이 없는 페이지로 자동 리디렉션되도록 벤 셰이르만의 답변을 편집했습니다.이름 매개 변수 RedirectUrl을 사용하여 리디렉션 경로를 변경할 수 있습니다.

편집: TarynMSDN의 조언 덕분에 솔루션을 스레드 세이프로 만들었습니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeRedirect : AuthorizeAttribute
{
    private const string IS_AUTHORIZED = "isAuthorized";

    public string RedirectUrl = "~/error/unauthorized";

    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        bool isAuthorized = base.AuthorizeCore(httpContext);

        httpContext.Items.Add(IS_AUTHORIZED, isAuthorized);

        return isAuthorized;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        var isAuthorized = filterContext.HttpContext.Items[IS_AUTHORIZED] != null 
            ? Convert.ToBoolean(filterContext.HttpContext.Items[IS_AUTHORIZED]) 
            : false;

        if (!isAuthorized && filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.RequestContext.HttpContext.Response.Redirect(RedirectUrl);
        }
    }
}

검색할 수 있습니다.?ReturnUrl=문자열 값을 쿼리하거나 고유한 권한 부여 필터를 만들고 필드를 설정할 수 있습니다.TempData이유를 표시합니다.

다음은 유용한 간단한 사용자 지정 필터입니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{

    // NOTE: This is not thread safe, it is much better to store this
    // value in HttpContext.Items.  See Ben Cull's answer below for an example.
    private bool _isAuthorized;

    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        _isAuthorized = base.AuthorizeCore(httpContext);
        return _isAuthorized;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if(!_isAuthorized)
        {
            filterContext.Controller.TempData.Add("RedirectReason", "Unauthorized");
        }
    }
}

그러면 다음과 같은 작업을 수행할 수 있습니다.

@if(TempData["RedirectReason"] == "Unauthorized")
{
    <b>You don't have permission to access that area</b>
}

(이 마법의 끈보다 더 나은 접근법을 추천하지만, 요점을 이해합니다.)

Ben Cull의 메서드는 잘 작동하지만 시스템에 두 개의 Authorize Attribute 클래스가 있습니다.Web.HTTP(Web API에서 사용) 및 System에서 다른 하나.Web.Mvc.Ben의 방법은 시스템을 사용합니다.웹.MVC 클래스.명확한 설명을 위해 완전한 경로를 사용하는 것이 좋습니다.

MVC와 함께 웹 API를 사용하는 경우 두 가지 필터를 구현해야 합니다.

public class AuthorizeRedirectMVCAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectResult("~/Account/AccessDenied");
        }
    }
}

public class AuthorizeRedirectAPIAttribute : System.Web.Http.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        base.HandleUnauthorizedRequest(actionContext);

        if (actionContext.RequestContext.Principal.Identity.IsAuthenticated)
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden);
        }
    }
}

참고로 asp.net 에서는 API 필터로 MVC 컨트롤러를 장식할 수 있습니다. 기대하는 방식으로 작동하지 않으므로 속성 이름을 명시적으로 유지하십시오.

컨트롤러가 있고 코드에 URL을 포함하지 않으려면 이 방법으로도 리디렉션할 수 있습니다.브라우저의 주소 표시줄에서 URL을 변경하지 않으므로 사용자는 권한 없는 페이지의 URL을 볼 수 없습니다.이것은 MVC 3에서 쓰여졌습니다.이 방법은 로그인 페이지로 리디렉션하려는 경우나 권한이 없다고 알려주는 페이지로 리디렉션하려는 경우에도 사용할 수 있습니다.프로그램에 권한이 없는 사용자가 로그인한 섹션이 있어서 사용했습니다.

public class AuthorizedRedirect : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool isAuthorized = base.AuthorizeCore(httpContext);
        return isAuthorized;
    }
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    filterContext.RequestContext.RouteData.Values["controller"] = "error";
    filterContext.Result = new ViewResult { ViewName = "unauthorized" };
}

또한 양식을 활용하는 더욱 단순한 버전입니다.인증 설정.계약, 계약에 익숙하지 않은 사람들을 위해.필수 항목은 입니다.NET 4 추가.코드 계약 사용에 대한 장단점.

public class RequiresAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        Contract.Requires(filterContext != null);

        HttpContextBase context = filterContext.RequestContext.HttpContext;

        if (context.User.Identity.IsAuthenticated)
        {
            // user does not possess the required role permission
            string url = context.GetCustomErrorUrl(401);
            context.Response.Redirect(url);
        }
        else
        {

            // redirect the user to the login page
            string extraQueryString  = context.Request.RawUrl;
            FormsAuthentication.RedirectToLoginPage(extraQueryString);
        }
    }
}

컨트롤러가 없더라도 divide_byzero의 답변에서 더 나아가 HandleUnauthorizedRequest를 사용하여 리디렉션을 변경할 수 있습니다.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AuthoriseRedirect : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.Redirect("UrlToRedirectTo");
        }
    }

장기간에 걸쳐 MVC로 변환할 레거시 웹 양식 사이트가 있는 경우 유용합니다...!

Brian Vander Plats가 올린 글이 마음에 듭니다. 몇 가지 개선 사항을 추가했습니다.

/// <summary>
/// Authorize or redirect to an unauthorized MVC action if the user does not have the required roles
/// (an unauthenticated user will be redirected to the defualt sign in action)
/// <para>Decorate an action or a controller like this [AuthorizeAndRedirect(Roles = "RoleName")]</para>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class AuthorizeOrRedirectAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            var routeData = new RouteData();
            routeData.Values.Add("controller", "Error");
            routeData.Values.Add("action", "Unauthorized");
            filterContext.Result = new RedirectToRouteResult(routeData.Values);
        }
    }
}

/// <summary>
/// Authorize or redirect to an unauthorized API action if the user does not have the required roles
/// (an unauthenticated user will be redirected to the defualt sign in action)
/// <para>Decorate an action or a controller like this [AuthorizeAndRedirect(Roles = "RoleName")]</para>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class AuthorizeOrRedirectApiFilterAttribute : System.Web.Http.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        base.HandleUnauthorizedRequest(actionContext);

        if (actionContext.RequestContext.Principal.Identity.IsAuthenticated)
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        }
    }
}

언급URL : https://stackoverflow.com/questions/1498727/asp-net-mvc-how-to-show-unauthorized-error-on-login-page

반응형