身份验证&通过数据注释进行授权

时间:2018-04-16 13:31:34

标签: c# asp.net-mvc data-annotations

我有一个数据库表,其中包含应允许对我的应用程序进行通用访问的所有用户。除此之外,还有一个名为IsAdministrator的bool列,如果这是真的,则允许该用户访问特定的操作/视图,例如创建新用户..删除现有的..等等。

我的目标是创建一种方法,以便在用户不是管理员时尝试访问创建操作/视图时,将其返回到错误视图页面。

我知道我可以这样做:

    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);
    }
}

2 个答案:

答案 0 :(得分:2)

这些方面应该做的事情:

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);
        }
    }
}

然后,您将在相关方法/类之前使用[CustomAuthorize]。此外,您需要确保初始化_context变量。

答案 1 :(得分:2)

为什么不是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 {
    [...]