请考虑以下代码块,这些代码块会在我的许多控制器操作中重新出现。(我主要关注方法主体的前6行)。
[HttpGet]
public ActionResult OptOut()
{
var user = this.SecurityPrincipal;
if (user.IsReadOnlyUser)
{
this.TempData["ViewModel"] = new AuthorizationModel { User = user };
return this.RedirectToAction("NotAuthorized", "Authorization");
}
var model = /* Elided for brevity */
return this.View(model);
}
我的控制器从基类派生,SecuredController
而基类又从派生Controller
。SecurityPrincipal
是的属性SecuredController
,并且包含有关当前用户的大量Active Directory数据。
为了消除重复的代码,理想情况下,我想将代码if {...}
块中包含的功能移至基类方法中,但我想不出任何办法,因为该方法的返回类型必须是ActionResult
,导致类似以下内容:
if ((var result = this.RequireReadWrite()) != null)
{
return result;
}
有人可以建议一种方法吗,还是我在这里很不幸?
正如评论中提到的,特别要注意安全性是一个跨领域的问题,我们建议在您的用例和设计中使用MVC动作过滤器。
Microsoft的文档非常有用,在网上可以找到有关如何使用MVC筛选器的更多示例。我将尝试提供一个示例,但这将基于您的软件体系结构上的许多假设,因为我完全不了解这一点。
您可以创建以下类:
public class SecuredFilterAttribute : AuthorizeAttribute
{
...
}
如果使用依赖注入框架,则可以注入SecurityPrincipal
服务。但是同样,我不知道您的应用程序的体系结构,因此由您决定如何创建依赖项。
覆盖时AuthorizeCore
,您可以这样实现:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return !this.SecurityPrinciple.IsReadOnlyUser;
}
并在未经授权时覆盖HandleUnauthorizedRequest
重定向的方法:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var redirectRoute = ...; //your route to redirect to an unauthorized page
filterContext.Result = new RedirectToRouteResult(redirectRoute);
//do some other things, for example, setting some tempdata information
}
再次取决于您如何使用此Filter。您可以在全球范围内注册它,也可以基于每个控制器或每个动作来应用它。要在注册时在全局范围内注册它,请执行以下操作:
GlobalFilters.Filters.Add(new SecuredFilterAttribute());
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句