【问题标题】:How do I restrict access to certain pages in ASP.NET MVC?如何限制对 ASP.NET MVC 中某些页面的访问?
【发布时间】:2023-04-09 05:29:01
【问题描述】:

如果

a) Identity.IsAuthenticated = false

或者他们已经过身份验证,但是

b) Idenitity.Name != 他们尝试编辑的用户页面的用户名
c) Identity.UserType() != UserType.Administrator // 这就像一个角色,没有使用 RoleProviders。

我假设你可以用一些东西来装饰控制器或控制器的操作方法,但我不确定是什么?

【问题讨论】:

    标签: asp.net-mvc authorization roles


    【解决方案1】:

    我实现了以下 ActionFilterAttribute,它可以同时处理身份验证和角色。我将角色存储在我自己的数据库表中,如下所示:

    • 用户
    • UserRole(包含 UserID 和 RoleID 外键)
    • 角色
    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,你有缓存用户或角色吗?
    • 我没有使用缓存——但我看不出分配给用户的角色列表无法缓存的原因。您可以在更改分配的角色时更新缓存。上面的代码与用户的缓存无关,因为我只是在查看当前用户的 httpcontext。我还应该提到,添加对允许用户的检查在原则上与检查允许的角色是相同的。
    【解决方案2】:

    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 ...但是这个属性 - 在那个时间点 - 如何知道视图数据是什么?或操作方法中的任何数据(我假设尚未运行,但..因为属性首先得到处理。
    • AuthorizationContext 参数包括对 Controller、HttpContext、ResultContext、RouteData 和 Result 的引用。您应该能够从 RouteData 中获得所需的一切。概括地说,向您的属性添加一个属性,该属性允许您指定用于用户名的路由数据键。你必须做数据库的东西来独立检查用户的类型。您可能需要两个构造函数:一个接受数据库上下文/层接口,另一个不接受参数并创建默认数据库上下文/层。在单元测试中使用前者。
    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 2022-11-26
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多