[.net] ASP.NET MVC에서 동적 로그인 URL로 리디렉션하는 방법
클라이언트 용 페이지를 호스팅하는 멀티 테넌시 웹 사이트를 만들고 있습니다. URL의 첫 번째 세그먼트는 다음 URL 라우팅 체계를 사용하여 Global.asax에 정의 된 클라이언트를 식별하는 문자열입니다.
"{client}/{controller}/{action}/{id}"
이것은 / foo / Home / Index와 같은 URL에서 잘 작동합니다.
그러나 [Authorize] 속성을 사용할 때 동일한 매핑 체계를 사용하는 로그인 페이지로 리디렉션하고 싶습니다. 따라서 클라이언트가 foo이면 로그인 페이지는 web.config에 정의 된 고정 / Account / Login 리디렉션 대신 / foo / Account / Login이됩니다.
MVC는 HttpUnauthorizedResult를 사용하여 401 무단 상태를 반환하는데, 이로 인해 ASP.NET이 web.config에 정의 된 페이지로 리디렉션됩니다.
그렇다면 누구나 ASP.NET 로그인 리디렉션 동작을 재정의하는 방법을 알고 있습니까? 아니면 사용자 지정 권한 부여 속성을 만들어 MVC에서 리디렉션하는 것이 더 낫습니까?
편집-답변 : .Net 소스를 파헤친 후 사용자 지정 인증 속성이 최상의 솔루션이라고 결정했습니다.
public class ClientAuthorizeAttribute: AuthorizeAttribute
{
public override void OnAuthorization( AuthorizationContext filterContext )
{
base.OnAuthorization( filterContext );
if (filterContext.Cancel && filterContext.Result is HttpUnauthorizedResult )
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "client", filterContext.RouteData.Values[ "client" ] },
{ "controller", "Account" },
{ "action", "Login" },
{ "ReturnUrl", filterContext.HttpContext.Request.RawUrl }
});
}
}
}
답변
주요 문제는 기본 제공 ASP.NET FormsAuthentication 클래스에 피기 백하려는 경우 (그렇게해서는 안되는 좋은 이유가 없습니다) 하루가 끝날 때 뭔가 호출 FormsAuthentication.RedirectToLoginPage()
될 것이라는 것입니다. 구성된 URL을 확인합니다. 로그인 URL은 단 하나 뿐이며 이것이 바로 그들이 디자인 한 방식입니다.
문제 (아마도 Rube Goldberg 구현)에 대한 나의 찌르는 것은 모든 클라이언트가 공유하는 루트의 단일 로그인 페이지 (예 : / account / login)로 리디렉션하는 것입니다. 이 로그인 페이지는 실제로 아무것도 표시하지 않습니다. ReturnUrl 매개 변수 또는 세션에있는 일부 값 또는 클라이언트를 식별하는 쿠키를 검사하고이를 사용하여 특정 / client / account / login 페이지에 대한 즉각적인 302 리디렉션을 발행합니다. 추가 리디렉션이지만 눈에 띄지 않을 가능성이 높으며 기본 제공 리디렉션 메커니즘을 사용할 수 있습니다.
다른 옵션은 설명 할 때 고유 한 사용자 지정 특성을 만들고 클래스 에서 RedirectToLoginPage()
메서드 를 호출하는 모든 것을 피하는 것입니다. FormsAuthentication
이를 고유 한 리디렉션 논리로 대체 할 것입니다. (비슷한 자신 만의 클래스를 만들 수도 있습니다.) 정적 클래스이기 때문에 자신의 대체 인터페이스를 주입하고 기존 [Authorize] 속성과 함께 마법처럼 작동하도록 할 수있는 메커니즘을 알지 못합니다. 불면,하지만 사람들은 전에 비슷한 일을 수행했다 .
도움이 되었기를 바랍니다.
답변
RTM 버전의 ASP.NET MVC에서 Cancel 속성이 없습니다. 이 코드는 ASP.NET MVC RTM에서 작동합니다.
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Resources;
namespace ePegasus.Web.ActionFilters
{
public class CustomAuthorize : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectToRouteResult(
new System.Web.Routing.RouteValueDictionary
{
{ "langCode", filterContext.RouteData.Values[ "langCode" ] },
{ "controller", "Account" },
{ "action", "Login" },
{ "ReturnUrl", filterContext.HttpContext.Request.RawUrl }
});
}
}
}
}
편집 : web.config에서 기본 양식 인증 loginUrl을 비활성화 할 수 있습니다 . 누군가 사용자 지정 속성이 있다는 사실을 잊어 버리고 실수로 내장 된 [Authorize] 속성을 사용하는 경우를 대비하십시오.
web.config에서 값을 수정합니다.
<forms loginUrl="~/Account/ERROR" timeout="2880" />
그런 다음 오류를 기록하고 사용자를 가장 일반적인 로그인 페이지로 리디렉션하는 작업 방법 ‘ERROR’를 만듭니다.
답변
이 문제에 대한 나의 해결책은 사용자 정의 ActionResult
클래스 였습니다 .
sealed public class RequiresLoginResult : ActionResult
{
override public void ExecuteResult (ControllerContext context)
{
var response = context.HttpContext.Response;
var url = FormsAuthentication.LoginUrl;
if (!string.IsNullOrWhiteSpace (url))
url += "?returnUrl=" + HttpUtility.UrlEncode (ReturnUrl);
response.Clear ();
response.StatusCode = 302;
response.RedirectLocation = url;
}
public RequiresLoginResult (string returnUrl = null)
{
ReturnUrl = returnUrl;
}
string ReturnUrl { get; set; }
}
답변
하나를 사용하기로 결정하면 여전히 내장 된 ASP.NET있는 FormsAuthentication, 하나는 오버라이드 (override)하는 수 Application_AuthenticateRequest
에서 Global.asax.cs
다음과 같이 :
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
string url = Request.RawUrl;
if (url.Contains(("Account/Login"))
{
return;
}
if (Context.User == null)
{
// Your custom tenant-aware logic
if (url.StartsWith("/foo"))
{
// Your custom login page.
Response.Redirect("/foo/Account/Login");
Response.End();
return;
}
}
}