1

背景故事

在我的应用程序中,一个身份用户与许多组织相关联,每个关联的行为类似于一个单独的“帐户”,但使用相同的登录名。在初始登录时,用户选择他们想要继续使用的帐户,这样做后,我创建一个声明(将任何现有声明擦除到该类型)并设置他们选择的帐户的 ID。

问题

目前我使用策略来检查我的控制器上是否填写了适当的 ID 声明,有什么方法可以使用我的策略将用户重定向到“帐户选择”页面?如果不是,那会被认为是 Asp.net 的方式。我应该检查每个控制器映射的方法吗?

使事情进一步复杂化

我的很多方法都是 Ajax 的返回类型 JSONResult,所以我可以预见自己必须在我的 JSON 中返回一个“直接到”字段,并在 JavaScript 中适当地处理它,如果它存在于响应中,是否有这样做的更好方法?


非常感谢

4

2 回答 2

1

如果未设置特定角色/声明,请使用应用于控制器的过滤器:

public class CheckAuthorizationFilter : ActionFilterAttribute 
{
    private static readonly List<string> Exceptions = new List<string>
        {
            "account/",
            "public/"
        };

    /// <summary>
    /// Called by the ASP.NET MVC framework before the action method executes.
    /// </summary>
    /// <param name="filterContext">The filter context.</param>
    public override void OnActionExecuting([NotNull] ActionExecutingContext filterContext)
    {
        Contract.Requires(filterContext != null);
        Contract.Requires(filterContext.HttpContext != null);
        Contract.Requires(filterContext.HttpContext.User != null);

        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            string actionName =
                $"{filterContext.ActionDescriptor.ControllerDescriptor.ControllerName}/{filterContext.ActionDescriptor.ActionName}"
                    .ToLower();
            if (!Exceptions.Any(actionName.StartsWith))
            {
                UserProfile user = UserProfileCache.Instance.Get(new TimeJackContext(),
                    new object[] {filterContext.HttpContext.User.Identity.GetUserId()});
                if (user == null || user.UserState != UserState.Active)
                {
                    SessionMessage.AddMessage(
                        $"You ({filterContext.HttpContext.User.Identity.Name}) are not allowed to use this smart tool at this time.", SessionMessage.MessageType.warning);
                    filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary
                        {
                            {"Controller", "Account"},
                            {"Action", "LogOff"}
                        });
                }
            }
        }
        base.OnActionExecuting(filterContext);
    }
}

并将过滤器添加到全局过滤器列表中:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    Contract.Requires(filters != null);
    filters.Add(new DatabaseUpgradeNeededFilter());
    filters.Add(new HandleErrorAttribute());
    filters.Add(new WarnAboutOldBrowsersAttribute());
    filters.Add(new CheckAuthorizationFilter()); // <---
    filters.Add(new RedirectToSslFilter());
    // ...
}
于 2016-02-04T16:03:59.003 回答
0

如果您使用cookie auth 中间件来持久化您的主体,那么您可以使用 Forbidden 设置来选择在策略评估失败时重定向到的页面;

app.UseCookieAuthentication(options =>
{
    options.AuthenticationScheme = "MyCookieMiddlewareInstance";
    options.LoginPath = new PathString("/Account/Login/");
    options.AccessDeniedPath = new PathString("/Account/Switch/");
    options.AutomaticAuthenticate = true;
    options.AutomaticChallenge = true;
});

然后在 /Account/Switch 中实现你的切换逻辑

于 2016-02-04T17:30:59.377 回答