通过数据注释进行身份验证和授权
Authentication & Authorization via Data Annotation
我有一个数据库 table,其中包含应允许对我的应用程序进行一般访问的所有用户。除此之外,还有一个名为 IsAdministrator
的 bool 列,如果为真,则允许该用户访问特定的 actions/views,例如创建新用户.. 删除现有的.. 等..
我的目标是创建一种方法,以便如果用户在不是管理员的情况下尝试访问创建 action/view,它会 returns 他们到错误视图页面。
我知道我可以做这样的事情:
public ActionResult Personnel()
{
// get user who is logged in
var personLoggedIn = User.Identity.Name.Split('\')[1]; // Intranet application.. so the domain name comes before the username hence the split
if(_context.UserTable.Single(x => x.UserLogon == personLoggedIn).IsAdministrator == false)
{
return View("Error");
}
// more code below
}
我想知道是否可以不将其复制并粘贴到每个不同的 actionresult 中。我可以将其放入数据注释中并用该数据注释装饰每个不同的 actionresult 吗?
更新
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using AuthorizeAttribute = System.Web.Http.AuthorizeAttribute;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AdministratorsOnly : AuthorizeAttribute
{
public AdministratorsOnly() { }
public override void OnAuthorization(AuthorizationContext filterContext)
{
var personLoggedIn = HttpContext.Current.User.Identity.Name.Split('\')[1];
using (var _context = new ConnectionStringName())
{
if (_context.UserTable.Single(x => x.UserLogon == personLoggedIn).IsAdministrator == false)
{
filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
base.OnAuthorization(filterContext);
}
}
按照这些思路应该可以做到:
public class CustomAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectResult("~/Error"); //Change "~/Error" to be the path to your error view
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
var personLoggedIn = filterContext.HttpContext.User.Identity.Name.Split('\')[1];
if (_context.UserTable.Single(x => x.UserLogon == personLoggedIn).IsAdministrator == false)
{
base.OnAuthorization(filterContext);
}
else
{
this.HandleUnauthorizedRequest(filterContext);
}
}
}
那么你会在相关的 methods/classes 之前使用 [CustomAuthorize]
。此外,您需要确保初始化 _context 变量。
为什么不是 AuthorizeAttribute
?
这样,所有 对控制器的请求都必须通过 OnAuthorization
方法。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AdminOnlyAttribute : AuthorizeAttribute
{
public AdminOnlyAttribute(){
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
//Here you will to figure out to
//have to access your Context with some DependencyResolver
//Exemple
var _context = ISomeInterface.ReturnCurrentContext();
var personLoggedIn = User.Identity.Name.Split('\')[1]; // Intranet application.. so the domain name comes before the username hence the split
if(_context.UserTable.Single(x => x.UserLogon == personLoggedIn).IsAdministrator == false)
{
filterContext.Result = new RedirectResult("~/PathToErrorView")
//Or even
filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest, "You don't have Access")
}
base.OnAuthorization(filterContext);
}
}
覆盖 OnAuthorization
方法,它会在您的控制器上发出的所有请求上调用
然后像这样使用:
[AdminOnly]
public class MyController {
[...]
我有一个数据库 table,其中包含应允许对我的应用程序进行一般访问的所有用户。除此之外,还有一个名为 IsAdministrator
的 bool 列,如果为真,则允许该用户访问特定的 actions/views,例如创建新用户.. 删除现有的.. 等..
我的目标是创建一种方法,以便如果用户在不是管理员的情况下尝试访问创建 action/view,它会 returns 他们到错误视图页面。
我知道我可以做这样的事情:
public ActionResult Personnel()
{
// get user who is logged in
var personLoggedIn = User.Identity.Name.Split('\')[1]; // Intranet application.. so the domain name comes before the username hence the split
if(_context.UserTable.Single(x => x.UserLogon == personLoggedIn).IsAdministrator == false)
{
return View("Error");
}
// more code below
}
我想知道是否可以不将其复制并粘贴到每个不同的 actionresult 中。我可以将其放入数据注释中并用该数据注释装饰每个不同的 actionresult 吗?
更新
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using AuthorizeAttribute = System.Web.Http.AuthorizeAttribute;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AdministratorsOnly : AuthorizeAttribute
{
public AdministratorsOnly() { }
public override void OnAuthorization(AuthorizationContext filterContext)
{
var personLoggedIn = HttpContext.Current.User.Identity.Name.Split('\')[1];
using (var _context = new ConnectionStringName())
{
if (_context.UserTable.Single(x => x.UserLogon == personLoggedIn).IsAdministrator == false)
{
filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
base.OnAuthorization(filterContext);
}
}
按照这些思路应该可以做到:
public class CustomAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectResult("~/Error"); //Change "~/Error" to be the path to your error view
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
var personLoggedIn = filterContext.HttpContext.User.Identity.Name.Split('\')[1];
if (_context.UserTable.Single(x => x.UserLogon == personLoggedIn).IsAdministrator == false)
{
base.OnAuthorization(filterContext);
}
else
{
this.HandleUnauthorizedRequest(filterContext);
}
}
}
那么你会在相关的 methods/classes 之前使用 [CustomAuthorize]
。此外,您需要确保初始化 _context 变量。
为什么不是 AuthorizeAttribute
?
这样,所有 对控制器的请求都必须通过 OnAuthorization
方法。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AdminOnlyAttribute : AuthorizeAttribute
{
public AdminOnlyAttribute(){
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
//Here you will to figure out to
//have to access your Context with some DependencyResolver
//Exemple
var _context = ISomeInterface.ReturnCurrentContext();
var personLoggedIn = User.Identity.Name.Split('\')[1]; // Intranet application.. so the domain name comes before the username hence the split
if(_context.UserTable.Single(x => x.UserLogon == personLoggedIn).IsAdministrator == false)
{
filterContext.Result = new RedirectResult("~/PathToErrorView")
//Or even
filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest, "You don't have Access")
}
base.OnAuthorization(filterContext);
}
}
覆盖 OnAuthorization
方法,它会在您的控制器上发出的所有请求上调用
然后像这样使用:
[AdminOnly]
public class MyController {
[...]