MVC3中的角色管理

时间:2011-06-07 10:30:34

标签: c# asp.net-mvc-3 user-roles

我想向应用程序添加一项功能,以便只有管理员可以创建用户,并且他可以向用户提供对特定页面的访问权。

他可以创建角色,并可以为用户提供不同的角色。

我正在使用Visual Studio 2010并在MVC3中构建此应用程序。

请给我一些建议。

提前致谢。

4 个答案:

答案 0 :(得分:13)

1.使用Authorize属性展示您的用户创建和权限设置操作 (通知,使用AuthorizeAttribute的Roles属性需要实现MembershipProvider(标准或自定义)并在web.config中注册它)

public class AccountController : Controller
{
[HttpGet, Authorize(Roles = "Admin")]
public ViewResult CreateUser()
{
    return View();
}

[HttpPost, Authorize(Roles = "Admin")]
public ActionResult CreateUser()
{
    //... call service method to create user
}

[HttpPost, Authorize(Roles = "Admin")]
public ActionResult AssignPageToUser(int userId, string controllerName, string ActionName)
{
    //... insert record into table (UserPermissions) with attributes (userId, actionName, controllerName)
    }
// other methods without decoration by authorize attribute
}

如果您真的想要为每个用户单独完全控制操作权限,则下一段是正确的。 如果您认为,您的权限可以在角色上分为有限数量和小数量 - 您可以通过授权属性装饰所有操作/控制器并指定角色,可用的操作/控制器为[Authorize("Customer, Manager, RegionalAdmin")]并为管理员提供分配角色的可能性给用户。但请记住,只有在列出的角色中只有1个才能获得访问权限,您不能要求此属性,例如Admin和Manager角色。 如果您想要需要多于1个角色,请使用多个属性:

public class MyController:Controller
{
[Authorize(Roles = "Manager")]
[Authorize(Roles = "Admin")]
public ActionResult Action1()
{
//...
}
}

2.对于您的页面,您可以创建自己的过滤器属性,继承自authorize属性,如果操作可供用户使用(我认为您要为用户分配操作但不是视图),则会检查。

public UserPermissionRequiredAttribute: AuthorizeAttribute
{
public OnAuthorization(AuthorizationContext filterContext)
{
var isAuthenticated = filterContext.HttpContext.User.Identity.IsAuthenticated;
var userName = filterContext.HttpContext.User.Identity.Name;
var actionName = filterContext.ActionDescriptior.ActionName;
var controllerName = filterContext.ActionDescriptior.ControllerDescriptor.ControllerName;
    if (isAuthenticated && myUserActionPermissionsService.UserCanAccessAction(userName, actionName, contollerName)
{
filterContext.Result = HttpUnauthorizedResult(); // aborts action executing
}
}
}

3.Decrate动作(控制器),可供管理员授予的用户访问:

MySpecialController: Controller
{
[UserPermissionRequired]
Action1()
{
//...
}

[UserPermissionRequired]
Action2()
{
//...
}

Action3()
{
//...
}

}

我不建议为此目的使用基本控制器,因为属性使用更灵活(您可以控制操作/控制器级别而不是仅控制器级别),这是实现分离责任的更好方法。基本控制器和过滤器属性用法关联为多态和切换操作符。

答案 1 :(得分:4)

您提出了一个非常广泛的问题,需要一些时间来审核您的所有要求。无论如何,您可以首先将用户属性添加到控制器,所有其他控制器都从该控制器继承。然后,您可以询问该用户实例以确定他们是否可以访问当前路由。此解决方案应为您提供为业务需求添加一些管理视图所需的基础。

public class MegaController
{
    protected User CurrentUser { get; set; }

    protected override void Initialize(RequestContext context)
    {
        if (requestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            var userRepository = new UserRepository();
            CurrentUser = userRepository.GetUser(
                requestContext.HttpContext.User.Identity.Name);
        }
    }
}

UserUserRepository类型可以是您自己的设计。您可以使用LINQ To Entities包装名为“User”的表,然后在您的控制器中,您可以访问该表中的任何字段。

然后,从MegaController

继承所有控制器
public class AdminController : MegaController
{
    public ActionResult Action1()
    {
        return View();
    }
}

public class SomeOtherController : MegaController
{
    public ActionResult Action1()
    {
        return View();
    }
}

现在,这并不能完全解决您的“管理员”问题。为此,您可以在MegaController.Initialize()中包含逻辑以询问请求信息。一旦您在上下文中获得了请求的路由和用户,您的代码就可以决定是否允许请求,重定向等等。

protected override void Initialize(RequestContext context)
{
    // ...
    if(context.HttpContext != null)
    {
        if(context.HttpContext.Request.Path == "some/restricted/route" 
            && CurrentUser.Role != "Admin")
        {
            // or similar error page
            var url = Url.Action("UnAuthorized", "Error");
            context.HttpContext.Response.Redirect(url);
        }
    }
}

使用此方法的一个警告是,添加到应用程序的任何新控制器都必须从MegaController继承,这个架构在项目中很容易被未来的开发人员遗漏。

答案 2 :(得分:2)

了解普通的旧表单身份验证以添加对角色和用户管理的支持。

然后使用控制器或操作上的[Authorize(Roles="RoleName1")]来控制访问。

答案 3 :(得分:1)

检查MvcMembership,也可在Nuget上找到。您将拥有ASP.NET MVC 3站点中用户管理的所有基础知识。

您需要一个用户/角色提供者。阅读this tutorial以了解如何设置可容纳您的用户和角色的数据库。设置完成后,您将拥有创建首次设置/手动测试所需的所有存储过程。