背景故事
在我的应用程序中,身份用户与许多组织相关联,每个关联的行为类似于单个"帐户",但在同一登录名下。在初始登录时,用户选择他们想要继续使用的帐户,这样做后,我创建一个声明(擦除该类型的任何现有声明(并设置他们选择的帐户的 ID。
问题
目前,我使用策略来检查是否已在我的控制器上填写了相应的 ID 声明,是否有任何方法可以使用我的策略将用户重定向到"帐户选择"页面?如果不是,什么会被认为是 Asp.net 方式。我是否应该对每个控制器映射方法执行检查?
使事情进一步复杂化
我的很多方法都是 Ajax 的返回类型 JSONResult,所以我可以预见自己必须在我的 JSON 中返回一个"直接到"字段,如果它存在于响应中,则在 JavaScript 中对其进行适当的处理,再次,有没有更好的方法做到这一点?
非常感谢
控制器的筛选器,以防未设置特定角色/声明:
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());
// ...
}
如果使用 cookie 身份验证中间件来保留主体,则可以使用"禁止"设置选择要在策略评估失败时重定向到的页面;
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 中实现切换逻辑