如何在ASP.NET MVC中限制访问某些页面?

5
我希望锁定用户的编辑页面(例如/user/pure.krome/edit)以防止以下情况:
a)Identity.IsAuthenticated = false b)已认证,但Identity.Name !=正在尝试编辑其用户名的用户页面
c)Identity.UserType()!= UserType.Administrator // 这类似于角色,而不是使用 RoleProviders。
我假设您可以使用某些东西对控制器或控制器的操作方法进行修饰,但我不确定使用什么?
3个回答

3

我使用从AuthorizeAttribute派生的自定义属性来实现这一点。重写OnAuthorize方法并实现您自己的逻辑。

public class OnlyUserAuthorizedAttribute : AuthorizeAttribute
{
    public override void OnAuthorize( AuthorizationContext filterContext )
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizeResult();
        }
        ...
    }
}

有趣...但是...我知道我需要用自己的逻辑替换你的逻辑。但是你的代码只回答了部分(a)。我也可以检查(c)。但是我不知道代码怎么知道要检查(b)。我有Identity.Name...但是这个属性-在那个时间点-怎么知道视图数据是什么?或者任何在动作方法中的数据(我假设还没有运行,因为属性会先处理)。 - Pure.Krome
AuthorizationContext参数包括对控制器、HttpContext、ResultContext、RouteData和Result的引用。您应该能够从RouteData中获取所需的所有内容。为了通用化,向属性添加一个属性,允许您指定用于用户名称的路由数据键。您将不得不执行DB操作以独立检查用户类型。您可能需要有两个构造函数:一个接受您的数据库上下文/层接口,另一个不带参数并创建默认数据库上下文/层。在单元测试中使用前者。 - tvanfosson

3
我实现了以下的ActionFilterAttribute,它可以处理认证和角色。我将角色存储在自己的数据库表中,如下所示:
  • User(用户)
  • UserRole(包含UserID和RoleID外键)
  • Role(角色)
public class CheckRoleAttribute : ActionFilterAttribute
{
    public string[] AllowedRoles { get; set; }


    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string userName = filterContext.HttpContext.User.Identity.Name;

        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            if (AllowedRoles.Count() > 0)
            {
                IUserRepository userRepository = new UserRepository();
                User user = userRepository.GetUser(userName);
                bool userAuthorized = false;
                foreach (Role userRole in user.Roles)
                {
                    userAuthorized = false;
                    foreach (string allowedRole in AllowedRoles)
                    {
                        if (userRole.Name == allowedRole)
                        {
                            userAuthorized = true;
                            break;
                        }
                    }
                }
                if (userAuthorized == false)
                {
                    filterContext.HttpContext.Response.Redirect("/Account/AccessViolation", true);
                }
            }
            else
            {
                filterContext.HttpContext.Response.Redirect("/Account/AccessViolation", true);
            }
        }
        else
        {
            filterContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl + String.Format("?ReturnUrl={0}", filterContext.HttpContext.Request.Url.AbsolutePath), true);
        }


    }

我称之为这样...

    [CheckRole(AllowedRoles = new string[] { "admin" })]
    public ActionResult Delete(int id)
    {
        //delete logic here
    }

在我上面的第一行中,我想说的是“身份验证和角色”。 - mikerennick
Mikerennick,您是否对用户或角色进行任何缓存? - Pure.Krome
我没有使用缓存,但我认为用户分配的角色列表可被缓存。当分配的角色发生更改时,您可以更新缓存。上述代码与用户缓存无关,因为我仅查看当前用户的httpcontext。我还应该提到,添加允许用户的检查原则上与允许角色的检查相同。 - mikerennick

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接