• mvc4 利用filters特性来 实现自己的权限验证 之二


    刚开始摸索C# MVC,也只是按图索骥,对C#的特性不是很懂,耐心看完相关文章,对特性的使用有了进一步理解。

    1.特性类的命名规范:特性也是一个类,必须继承于System.Attribute类,命名规范为“类名”+Attribute。不管是直接还是间接继承,都会成为一个特性类,特性类的声明定义了一种可以放置在声明之上新的特性。

    2.特性的使用:[特性类名(不需要后缀Attribute)(公共属性=值, 公共属性=值...)]放置于类、方法、字段、属性、结构体...前修饰。

      如:

    //在Person类上标记ClassMsg特性
    [ClassMsg(Msg = "这是关于人的姓名信息的类")]
    class Person
    {
    //在_name字段上应用ClassMsg特性
    [ClassMsg("这是存储姓名的字段")]
    string _name;
    //[ClassMsg("这是读写姓名字段的属性")]
    public string Name { get { return _name; } set { _name = value; } }
    }

    3.特性类的应用限定修饰:

    使用AttributeUsage,来控制如何应用新定义的特性,放置于特性类定义前。

    [AttributeUsageAttribute(AttributeTargets.All //可以应用到任何元素
    
    ,AllowMultiple=true, //允许应用多次,我们的定值特性能否被重复放在同一个程序实体前多次。
    
    ,Inherited=false,//不继承到派生
    
    )]

    4.特性的应用

    (1).net中特性用来处理多种问题,比如序列化、程序的安全特性、防止即时编译器对程序代码进行优化从而代码容易调试等等。

    定植特性的本质上是一个类的元素上去添加附加信息,并在运行其通过反射得到该附加信息(在使用数据实体对象时经常用到)

    (2)Attribute 作为编译器的指令时的应用

    Conditional:起条件编译的作用,只有满足条件,才允许编译器对它的代码进行编译。一般在程序调试的时候使用

    DllImport: 用来标记费.net的函数,表明该方法在一个外部的DLL中定义。

    Obsolete: 这个属性用来标记当前的方法已经废弃,不再使用

    注:Attribute是一个类,因此DllImport也是一个类,Attribute类是在编译的时候实例化,而不是像通常那样在运行时实例化。

    CLSCompliant: 保证整个程序集代码遵守CLS,否则编译将报错。

    昨天写的《mvc4 利用filters特性来 实现自己的权限验证》  不需要注册全局的Filters来实现,即第2步不需要。全局的Filter所有的请求都会都会触发。

    修改为:

    mvc4 利用特性类过滤,实现自己的权限验证 

    1.新建一个特性类AdminAuthorize继承ActionFilterAttribute。重写OnActionExecuting,在执行action前执行,在这里进行权限判断,在switch可定义多种权限。

    代码:Filters/AdminAuthorizeAttribute.cs

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Web;
     6 using System.Web.Mvc;
     7 using System.Web.Profile;
     8 using System.Web.Routing;
     9 using System.Web.Security;
    10 namespace XyguiMvcApp.Filters
    11 {
    12     //限制Attribute类的使用
    13     [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
    14     public class AdminAuthorizeAttribute : ActionFilterAttribute
    15     {
    16         /// <summary>
    17         ///  角色
    18         /// </summary>
    19         private string role = "";
    20         /// <summary>
    21         /// 摘要:获取或设置用户角色。
    22         // 返回结果:用户角色。
    23         /// </summary>
    24         public string Role
    25         {
    26             get { return role; }
    27             set { role = value; }
    28         }
    29 
    30         public override void OnActionExecuting(ActionExecutedContext filterContext)
    31         {
    32             switch (role)
    33             {
    34                 case "Admin":   //Admin角色权限检查。
    35                     var cookie = System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    36                     if (cookie != null && FormsAuthentication.Decrypt(cookie.Value).UserData == role)
    37                     {
    38                         //验证通过
    39                     }
    40                     else
    41                     {
    42                         string returnUrl = HttpContext.Current.Request.Url.PathAndQuery;
    43                         var url = FormsAuthentication.LoginUrl + "?returnUrl=" + HttpUtility.UrlEncode(returnUrl);
    44                         //HttpContext.Current.Response.Redirect(url, true);//进入action
    45                         //filterContext.HttpContext.Response.Redirect(url);//进入action
    46                         /*filterContext.Result = new RedirectToRouteResult( //不进入action
    47                         new RouteValueDictionary
    48                         {
    49                             { "action", "Login" },
    50                             { "controller", "Admin" },
    51                             {"returnUrl", returnUrl}
    52                         });*/
    53                         filterContext.Result = new RedirectResult(url);//不进入action,转到登录页面。                    
    54                     }
    55 
    56                     break;
    57                 case "Anyone":  //任何人。
    58 
    59                     break; 
    60                 case "Guest":  //Guest权限
    61 
    62                     break;
    63                 default:
    64 
    65                     break;
    66 
    67             }
    68 
    69         }
    70     }
    71 }
    查看代码

    3.在action前添加特性[AdminAuthorize(Role = "Admin")] ,这里断点发现只有第一次调用action才实例化AdminAuthorizeAttribute类,而OnActionExecuted每次调用action都会触发。

    如:

     1         [AdminAuthorize(Role = "Anyone")]
     2         public ActionResult Index()
     3         {
     4             return View();
     5         }
     6 
     7         [AdminAuthorize(Role = "Admin")]
     8         public ActionResult Main()
     9         {
    10 
    11             return View();
    12         }

    4.配置web.config

    <authentication mode="Forms">
      <forms name=".AuthAdmin" loginUrl="~/Admin/Login" timeout="30" protection="All" path="/Admin" defaultUrl="/Admin/Main" />
    </authentication>

    5.在登录action,Login注册船票ticket

    复制代码
     1 FormsAuthenticationTicket MyTicket = new FormsAuthenticationTicket
     2 (
     3 1,
     4 admin.UserName+"," + admin.NickName,
     5 DateTime.Now,
     6 DateTime.Now.AddMinutes(300),
     7 true,
     8 "Admin",
     9 FormsAuthentication.FormsCookiePath
    10 );
    11 
    12 //添加 Cookies
    13 string myHash = FormsAuthentication.Encrypt(MyTicket);
    14 HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName, myHash);
    15 Response.Cookies.Add(myCookie);
    复制代码
  • 相关阅读:
    当安装、卸载件包时,出现依赖问题 error: Failed dependencies解决办法
    保险业务逻辑漏洞新姿势
    Office远程代码执行漏洞(CVE-2017-11882)
    centos7卸载mariadb安装mysql
    Burp时间到期之复活
    weblogic 安装+部署(一)
    nessus 本地扫描(一)
    nessus 家庭版安装教程(windows)
    linux 漏洞列表
    关于MYSQL通过子查询删除重复数据的for update报错问题解决
  • 原文地址:https://www.cnblogs.com/xygui/p/5587428.html
Copyright © 2020-2023  润新知