多个表单登录页面

时间:2012-01-17 14:33:06

标签: asp.net-mvc-3 c#-4.0 razor web-config asp.net-mvc-3-areas

我有一个MVC3网站,其中包含管理站点和面向公众的站点。这些控制器,视图,模型等都在同一个MVC项目中。它们是分开的:管理站点位于名为Admin的MVC3区域中,面向公众的站点不属于某个区域,但存在于顶层。管理站点具有“登录”视图,公共站点也具有“登录”视图。在我的web.config文件中,我有:

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogIn" timeout="2880" />
</authentication>

现在,如果我访问公共站点中需要身份验证的任何页面,我会进入公共站点的登录页面,这很棒。但是,如果我访问管理区域中需要身份验证的任何页面,那么我将再次进入公共站点的登录页面。那么问题是如何确保如果我在管理区域中需要身份验证的页面上,我会被发送到管理员登录页面?

3 个答案:

答案 0 :(得分:7)

当需要本地化登录页面时,我遇到了类似的问题。 我创建了一个自定义Authorize属性:

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 
                    { 
                            { "language", filterContext.RouteData.Values[ "language" ] }, 
                            { "controller", "Account" }, 
                            { "action", "LogOn" }, 
                            { "ReturnUrl", filterContext.HttpContext.Request.RawUrl } 
                    });
        }
    }
}

只需使用此属性而不是默认的Authorize属性。 在您的情况下,您可以检查请求网址,并根据该重定向到相应的登录页面。

答案 1 :(得分:3)

您可以编写自定义Authorize属性并覆盖HandleUnauthorizedRequest方法,在该方法中您可以测试是否在管理员上发出请求,并相应地重定向。

有些事情:

public class MyAuthorizeAttribute: AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var area = filterContext.RequestContext.RouteData.Values["area"] as string;
        if (string.Equals("admin", area, StringComparison.OrdinalIgnoreCase))
        {
            // if the request was for a resource inside the admin area
            // redirect to a different login page than the one in web.config
            // in this particular case we redirect to the index action
            // of the login controller in the admin area. Adapt this
            // accordingly to your needs. You could also externalize this 
            // url in the web.config and fetch it from there if you want

            var requestUrl = filterContext.HttpContext.Request.Url;
            var urlHelper = new UrlHelper(filterContext.RequestContext);
            var url = urlHelper.Action(
                "index", 
                "login", 
                new 
                { 
                    area = "admin", 
                    returnUrl = requestUrl.ToString() 
                }
            );
            filterContext.Result = new RedirectResult(url);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

现在使用此自定义授权属性而不是默认属性。

答案 2 :(得分:0)

请务必使用 filterContext.RouteData.DataTokens [&#34; area&#34;]; 而不是 filterContext.RouteData.Values [&#34; area&#34;] ;

public class AreaAuthorizeAttribute : AuthorizeAttribute
{
    public string LoginController = "Account";
    public string LoginAction = "Login";

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        if (filterContext.Result is HttpUnauthorizedResult)
        {
            var area = filterContext.RouteData.DataTokens["area"];
            filterContext.Result = new RedirectToRouteResult(
                new System.Web.Routing.RouteValueDictionary 
                { 
                    { "area", area},
                    { "controller", LoginController }, 
                    { "action", LoginAction }, 
                    { "ReturnUrl", filterContext.HttpContext.Request.RawUrl } 
                });
        }
    }

像这样使用:

[AreaAuthorizeAttribute(LoginController =&#34; AreaLoginController&#34;,Role =&#34; Administrator&#34;)]