如何允许具有管理员权限的用户访问控制器

时间:2014-09-17 13:20:51

标签: c# asp.net asp.net-mvc entity-framework asp.net-mvc-5

我有一个使用Windows身份验证的应用程序。没有太详细,我的应用程序设置了一系列用户,然后给予管理员权限来创建缺席。如果他们没有管理员权限,那么他们就无法更改用户或创建缺席。

我想根据数据库中的admin标志是否设置为true来限制对某些控制器/操作的访问。我工作的用户属于多个组,没有管理员组,我可以将其包含在Authorize属性角色字符串中。

我遵循了教程here,但由于我有一个数据库第一个实体框架模型,所以实体类继承自DbContext而不是来自身份上下文。

当我运行应用程序时,我的代码引发了一个错误说:"类型' System.InvalidOperationException'发生在mscorlib.dll中但未在用户代码中处理

附加信息:实体类型IdentityRole不是当前上下文模型的一部分。"我点击查看详细信息,我看到了这个"实体类型IdentityRole不是当前上下文模型的一部分。"

这是发生错误的代码片段:

        AbsencesEntities context = new AbsencesEntities();

        AbsenceRepository absenceRepository = new AbsenceRepository(context);
        IdentityResult IdRoleResult;
        IdentityResult IdUserResult;

        // Create a RoleStore object by using the UserSecurity object.
        // The RoleStore is only allowed to contain IdentityRole objects.
        var roleStore = new RoleStore<IdentityRole>(context);

        // Create a RoleManager object that is only allowed to contain IdentityRole objects
        // When creating the RoleManager object, you pass in (as a parameter) a new RoleStore
        var roleMgr = new RoleManager<IdentityRole>(roleStore);

        // Then, you create the "canEdit" role if it doesn't already exist
        if(!roleMgr.RoleExists("canEdit"))
        {
            IdRoleResult = roleMgr.Create(new IdentityRole { Name = "canEdit" });
        }

只是为了澄清我没有在配置文件中指定任何其他上下文。

我必须有办法使用Windows身份验证并使用返回的LAN ID来检查它是否存在于数据库中。然后使用它来检查数据库中的Admin标志是否为true。

2 个答案:

答案 0 :(得分:5)

您可以从authorizeattribute继承并覆盖authorizecore,然后使用该属性装饰您的控制器和/或方法以处理此方案。例如:

public class PageAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (/*Rolemanager check*/) {
            return true;
        }
        return false;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
        {
            {"action", "PageDenied"}
            ,
            {"controller", "Authorization"}
        });
    }
}

您可以使用httpContext.User.Identity.Name来检查用户名。

[PageAuthorize]
public class PageController : Controller
{}

答案 1 :(得分:1)

将Authorize属性设置为整个控制器:

[Authorize(Roles = "Administrator")]
    public class AdminController : Controller
    {

但为了使其成功,您需要: 创建自定义主体和标识:

public class CustomIdentity : IIdentity
{
    private bool _IsAdmin;
    public bool IsAdmin
    {
        get { return _IsAdmin; }
    }

    // other properties
    public CustomIdentity(string Login)
    {
        using(DbContext db = new DbContext())
        {
        User user = db.Users.FirstOrDefault(u => u.Login.Equals(Login, StringComparison.CurrentCultureIgnoreCase));
        _IsAdmin = user.IsAdmin;
        }
    }
}

public class CustomPrincipal : IPrincipal
{
    private CustomIdentity _Identity;
    public CustomPrincipal(string Login)
    {
        _Identity = new CustomIdentity(Login);
    }
    public bool IsInRole(string role)
    {
        if (_Identity != null)
        {
            return role == "Administrator"? _Identity.IsAdmin: false;
        }
        else
        {
            return false;
        }
    }
    //other properties and code
}

在global.asax中覆盖PostAuthRequest:

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
    if (User.Identity != null && User.Identity.IsAuthenticated)
    {
        CustomPrincipal opPrincipal = new CustomPrincipal(User.Identity.Name);
        HttpContext.Current.User = opPrincipal;
    }
}

您应该将列Login和相同的属性添加到User表和类。