将自定义安全方法应用于所有操作

时间:2014-10-01 22:12:55

标签: c# asp.net-mvc asp.net-mvc-4

我有一个返回bool的方法,因为允许用户访问该站点,而用户无法访问该站点。截至目前,我在每个Action中都有一个单独的操作,如果用户返回false,则用户将被定向到一个视图,表示"访问被拒绝"。我想知道有一种更好的方法可以做到这一点而不会在每个单独的操作中抛出重复的代码,任何可能用一个单独的调用替换它,因为用户将能够访问所有页面或非页面。

以下是我的例子:

    [HttpGet]
    public ActionResult EmployeeAdd()
    {
        if (!GetUsersecurityLevel())
        {
            return RedirectToAction("NotAuthorizedForApplication");
        }

        ...........

        return View();
    }

    [HttpGet]
    public ActionResult EmployeeEdit()
    {
        if (!GetUsersecurityLevel())
        {
            return RedirectToAction("NotAuthorizedForApplication");
        }

        ..........

        return View();
    }

    [HttpGet]
    public ActionResult EmployeeDelete()
    {
        if (!GetUsersecurityLevel())
        {
            return RedirectToAction("NotAuthorizedForApplication");
        }

        ..........

        return View();
    }


    public string CurrentUserName()
    {
        return User.Identity.Name.Substring(User.Identity.Name.IndexOf(@"\", StringComparison.Ordinal) + 1).ToUpper();
    }

Web.Config中:

  <system.web>
    <authentication mode="Windows" />
    <authorization><deny users="?"/></authorization>
    <compilation debug="true" targetFramework="4.0"/>
    <httpRuntime targetFramework="4.0"/>
    <customErrors mode="Off" />
  </system.web>

所以我的问题是:我可以在GetUserSecurityLevel()上进行一次调用,这可以保护所有操作不被未经授权的用户运行吗?

3 个答案:

答案 0 :(得分:3)

创建一个自定义授权属性,如下所示:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var username = httpContext.User.Identity.Name;
        return GetUserSecurityLevel(username);
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {            
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (!AuthorizeCore(filterContext.HttpContext))
        {
             // If not authorized, redirect to the NotAuthorizedForApplication action 
             filterContext.Result = new RedirectToRouteResult(
                new System.Web.Routing.RouteValueDictionary {
                   {"action", "NotAuthorizedForApplication"}
                }
             );               
        }
    }

    private bool GetUserSecurityLevel(string username)
    {
        // Your code to authorize users...
    }
}

然后,您可以在控制器中使用它或这样的操作:

[HttpGet]
[MyAuthorize]
public ActionResult EmployeeAdd()
{
    ...........

    return View();
}

但是,如果只有一个级别的访问权限,为什么不使用NT组(角色)进行授权?

<强>更新

确保在IIS上启用了Windows身份验证,并在web.config文件中的<system.web>内启用了Windows身份验证:

<authentication mode="Windows" />
<authorization>
  <deny users="?" />
</authorization>

答案 1 :(得分:1)

以下内容对您有所帮助。一旦覆盖了AuthorizeCore,就可以在控制器中使用它,它将适用于您的所有操作。您也可以单独将它应用于每个操作方法

 public class AdminAuthorizeAttribute: AuthorizeAttribute
     {

      protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
          {
              return !base.AuthorizeCore(httpContext)? false:GetUsersecurityLevel();
          }
     }

然后在控制器上

你可以做到

在控制器级别

 [AdminAuthorize]
 public class YourController:Controller 
       {

       }

或行动级别

 [HttpGet]
 [AdminAuthorize]
 public ActionResult EmployeeAdd()

答案 2 :(得分:0)

自定义授权过滤器是ataravati建议的最佳解决方案。