• ASP.NET权限管理


    ASP.NET Web Forms权限管理:

    我要将一个文件夹只能让一个用户组访问怎么办?

    可否在网站根目录下的web.config里这样设置:

    <location path="admin">
    
        <system.web>
    
          <authorization>
    
            <allow roles="adminer">
    
            </allow>
    
            <deny users="*">
    
            </deny>
    
          </authorization>
    
        </system.web>
    
      </location>

    (注:最后经过测试,这样是可以的,这里只是为了说明web.config是分层,可覆盖的)

    最后我想到,在每个文件夹下加一个web.config重写

    <authorization/>部分

    如:

    a文件夹下web.config:

    <?xml version="1.0" encoding="utf-8" ?>
    
    <configuration> 
    
      <system.web>
    
          <authorization>
    
                <allow  roles = "admin"/>
    
                <deny   user  = "?"/>
    
        </authorization>
    
     </system.web>
    
    </configuration>

    b文件夹下的web.congfig

    <?xml version="1.0" encoding="utf-8" ?>
    
    <configuration> 
    
      <system.web>
    
          <authorization>
    
                <allow  roles="teacher"/>
    
                  <deny users = "?" roles = "student,admin"/>
    
        </authorization>
    
     </system.web>
    
    </configuration>

    这样就对不同的文件夹实现不同的授权了

    基于角色的验证终于完成了

    如下实现方法:

    1.在web.config里这样设置:

    <system.web>
    
           <authorization>
    
                  <allow = “roleslist”/>
    
                  <deny users = “?”/>
    
           </authorization>
    
    </system.webconfig>

    登陆成功以后生成一个票据,票据里存储有用户的用户名和角色等信息,将票据发送到客户端,并跳转到请求的页面。

    如:

    //如果通过验证
    
    if (IsPass)
    
    {
    
         FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,studentinfo.userid,DateTime.Now,DateTime.Now.AddMinutes(30),false,studentinfo.role,"/");
    
         string CodeTicket = FormsAuthentication.Encrypt(ticket);
    
         HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,CodeTicket);
    
         Context.Response.Cookies.Add(cookie);
    
         Context.Response.Redirect(RedirectTarget);
    
    }

    2.在Gloabal.asa.cs里的Application_AuthenticateRequest中获取客户端的cookie中的role信息,并生成GenericPrincipal对象保存在Application.Conext.User里

    如:

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    
    {
    
         HttpApplication App = (HttpApplication) sender;
    
         HttpContext Ctx = App.Context ; //获取本次Http请求相关的HttpContext对象
    
         if (Ctx.Request.IsAuthenticated == true) //验证过的用户才进行role的处理
    
         {
    
             FormsIdentity Id = (FormsIdentity)Ctx.User.Identity ;
    
             FormsAuthenticationTicket Ticket = Id.Ticket ; //取得身份验证票
    
             string[] Roles = Ticket.UserData.Split (',') ; //将身份验证票中的role数据//转成字符串数组
    
             Ctx.User = new GenericPrincipal (Id, Roles) ; //将原有的Identity加上角色信//息新建一个GenericPrincipal表示当前用户,这样当前用户就拥有了role信息
    
         }
    
    }

    使用这种权限管理的前提是Web Forms进行开发,在MVC框架中,这种方法却无法正常工作,原因有两点:

    • 请求不再映射到物理目录。
    • 可能存在多种查找同一控制器的方式。

     ASP.NET MVC权限管理:

    Authorize特性是ASP.NET MVC自带的默认授权过滤器,可用来限制用户对操作方法的访问。

    对于大多数网站来说,基本上整个应用程序都是需要授权的。因此,把AuthorizeAttribute配置为全局过滤器,使用AllowAnonymous特性匿名访问指定控制器或方法,就变成了不错的想法。

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new System.Web.Mvc.AuthorizeAttribute());
        filters.Add(new HandleErrorAttribute());
    }

    这样就会把AuthorizeAttribute应用到整个程序的所有控制器操作。显而易见,这样也限制了对整个网站的访问。MVC4中新添加了AllowAnonymous特性,用AllowAnonymous特性装饰的方法能够匿名访问。

    我们也能限制特定用户或角色的访问,Authorize特性允许指定角色和用户:

    [Authorize(Roles = "Administrator,SuperAdmin", Users = "Jon,Phil")]
    public class TopSecretController : Controller

    值得注意的是全局过滤器只针对MVC控制器操作,不能保障Web Forms、静态内容或其他ASP.NET处理程序的安全。

    除了使用过滤器控制权限,我们可以在运行Controller之前来判断用户操作权限,那么我们可以试想此处的应用场景,如当我们的用户未认证,那么我们可以通过直接判断跳转到认证页面。

    具体实现方法:重写Controller里面的OnActionExecuting,需要授权认证的控制器继承重写后的Controller。

    /// <summary>
    /// 在执行操作方法之前由 MVC 框架调用,我们在此实现我们的权限验证
    /// </summary>
    /// <param name="filterContext"></param>
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        int statusCode = 200;//200:成功,401:未登录,403:没有权限
        string url = Request.RawUrl.ToLower();
        if (Method.isLogin())
        {
            if (!checkAuthority(url))
            {
                statusCode = 403;
            }
        }
        else
        {
            statusCode = 401;
        }
        if (statusCode != 200)//未通过授权
        {
            if (url.Contains("/api"))//api异步请求返回状态码
            {
                var json = new
                {
                    result = statusCode
                };
                filterContext.Result = Json(json, JsonRequestBehavior.AllowGet);
            }
            else//页面请求跳转
            {
                //filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = "Login", action = "Login" }));
                switch (statusCode)
                {
                    case 401:
                        filterContext.Result = RedirectToAction("Login", "Login");
                        break;
                    case 403:
                        filterContext.Result = RedirectToAction("NoAuthority", "Login");
                        break;
                }
            }
        }
    }

    其中的checkAuthority()方法判断管理员的权限:

    /// <summary>
    /// 权限判断
    /// </summary>
    /// <param name="power"></param>
    private bool checkAuthority(string url)
    {
        string[] arr = Method.getAdminInfo["authority"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        string val = "";
        switch (url)
        {
        
    //权限100 查看会员 case "/member/mymember": val = "100"; break; //权限101 修改会员 case "/api/editmember": val = "101"; break; } if (val != "")//该页面需要权限进入 { return arr.Contains(val); } else { return true; }
    }
    其中的Method.getAdminInfo["authority"]是我写的获取登录票据中管理员的权限(用“,”分割的数字)。

     

    RBAC数据库设计图:

     


    原文参考:.net用户角色与访问权限控制

         大型门户网站的RBAC用户权限管理

         《ASP.NET MVC4 高级编程》(第四版)

  • 相关阅读:
    AGC030 简要题解
    CF1601 简要题解
    CSP2021 题解
    2021.11.1-2021.11.7总结
    超快速梅森旋转SFMT(SIMD-oriented Fast Mersenne Twister)一览
    2021.10.25-2021.10.31总结
    CSP 2021 游记
    在Windows vs2015环境下编译使用Libevent
    在Windows环境下实现一个简单的libevent服务器
    Thinking in C++ 课后习题自己实现 第二章
  • 原文地址:https://www.cnblogs.com/qtxy/p/4788095.html
Copyright © 2020-2023  润新知