我正在创建一个多租户网站,为客户托管页面.URL的第一段将是一个字符串,用于标识在Global中定义的客户端.asax使用以下URL路由方案:

"{client}/{controller}/{action}/{id}"

这在使用/foo/Home/Index等URL时效果很好.

然而,当使用[Authorize]属性时,我想重定向到一个同样使用相同映射方案的登录页面.因此,如果客户端是foo,那么登录页面将是/foo/Account/login,而不是web中定义的固定/Account/login重定向.配置.

MVC使用HttpUnauthorizedResult返回401 Unauthorized状态,我认为这会导致ASP.NET重定向到web中定义的页面.配置.

那么,有人知道如何覆盖ASP.网络登录重定向行为?还是通过创建自定义授权属性在MVC中重定向更好?

EDIT - Answer:在深入研究了.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参数或会话中的某个值,或识别客户端的cookie,并使用它立即发出302重定向到特定的/client/account/login页面.这是一个额外的重定向,但可能不明显,它允许您使用内置的重定向机制.

另一种 Select 是在描述时创建自己的自定义属性,并避免调用FormsAuthentication类上的RedirectToLoginPage()方法的任何内容,因为您将用自己的重定向逻辑替换它.(您可以创建自己的类似类.)因为它是一个静电类,我不知道有什么机制可以简单地注入您自己的替代接口,并让它神奇地与现有的[Authorize]属性一起工作,这很糟糕,但是是people have done similar things before%.

希望有帮助!

.net相关问答推荐

删除数据库项目中的表

如何按需计算一个值并将该值缓存在FP/F#中?

移位比Java中的乘法和除法更快吗? .网?

在c#中计算中位数

C#6.0 字符串插值本地化

是否可以像 WebView 一样在 Windows 窗体中嵌入 Gecko 或 Webkit?

OpenCV的.Net(dotNet)包装器?

struct 中需要覆盖什么以确保平等正常运行?

如何在 WPF 中创建/制作圆角按钮?

返回 IList 是否比返回 T[] 或 List 更糟糕?

设置 System.Drawing.Color 值

将日期时间转换为时间跨度

在 .NET Core 中在 MVC 之外使用 Razor

使 HashSet 不区分大小写

嵌套的 Try/Catch 块是个坏主意吗?

安装带有恢复操作的 Windows 服务以重新启动

表单不响应 KeyDown 事件

如何在不使用 3rd 方库的情况下登录 C#?

C# - 在 WPF 应用程序中保存用户设置的方法?

当它被抛出和捕获时,不要在那个异常处停止调试器