.Net core---Filter3

ResultFilter

在视图渲染之前或者之后执行的操作

1.新建一个CustomResultFilterAttribute类,实现IResultFilter接口

 public class CustomResultFilterAttribute : Attribute, IResultFilter
    {
        /// <summary>
        /// 渲染视图之前执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine("渲染视图之前执行");
        }
        /// <summary>
        /// 渲染视图之后执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine("渲染视图之后执行");
        }
    }

2.应用

 [CustomResultFilterAttribute]
        public IActionResult IndexResult()
        {
            return View();
        }

结果

ResultFilter的应用
语言的切换,其实就需要两个视图;要根据语言的不同,来选择不同的视图来渲染;

1.CustomResultFilterAttribute.cs

 public class CustomResultFilterAttribute : Attribute, IResultFilter
    {
        private IModelMetadataProvider _modelMetadataProvider = null;
        public CustomResultFilterAttribute(IModelMetadataProvider modelMetadataProvider)
        {
            _modelMetadataProvider = modelMetadataProvider;
        }
        /// <summary>
        /// 渲染视图之前执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine("渲染视图之前执行");
            //在这里就可以有一个判断,符合某个情况,就使用哪一个视图;
            string view = context.HttpContext.Request.Query["view"];//可以是配置文件
            if (view == "1")//中文
            {
                var result = new ViewResult { ViewName = "~/Views/ActionF/IndexResult.cshtml" };
                result.ViewData = new ViewDataDictionary(_modelMetadataProvider,context.ModelState);
                context.Result = result;
            }
            else
            {
                var result = new ViewResult { ViewName = "~/Views/ActionF/IndexResult_2.cshtml" };
                result.ViewData = new ViewDataDictionary(_modelMetadataProvider, context.ModelState);
                context.Result = result;
            }
        }
        /// <summary>
        /// 渲染视图之后执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine("渲染视图之后执行");
        }

2.使用

      //[CustomResultFilterAttribute]
        [TypeFilter(typeof(CustomResultFilterAttribute))]
        public IActionResult IndexResult()
        {
            return View();
        }

鉴权授权
为了拦截一些操作:
传统的授权方式: session/Cookies来完成


.Net5鉴权授权

通过中间件来支持;
1.startup.cs中 Configure方法

   在app.UseRouting();之后,在app.UseEndpoints() 之前,增加鉴权授权:
    鉴权: app.UseAuthenticaton0;-----------检测用户是否登录
    授权: app.UseAuthorization();:----------授权检测有没有权限,是否能够访问后续的页面功能


2.在ConfigureServices中增加

    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(option=> 
                {
                    option.LoginPath = new PathString("/Home/Login");//如果授权失败,就跳转到这个路径
                });

 3.指定哪些Action需要做鉴权授权
标记特性:也可以标记在控制器,全局;

[Microsoft.AspNetCore.Authorization.Authorize]

4.当Authorize标记为控制器、全局,可以使用匿名(自定义)避开权限检查 [AllowAnonymousAttribute]

登录Demo

1.

2.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(option=> 
                {
                    option.LoginPath = new PathString("/Home/Login");//如果授权失败,就跳转到这个路径
                });

3.编写一个简易的登录页面Login.cshtml

@{
    ViewData["Login"] = "login Page";
}
<div>
    <h1>Login</h1>
    <div style="color:orangered;">@ViewBag.Msg </div>
    <div>
        <form action="
/Home/Login" method="post">
            <input type="text" name="name" />
            <br />
            <input type="text" name="password" />
            <br />
             <input type="submit" value="提交"/>
        </form>
    </div>
</div>

4.Controller

public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        [Authorize]
        public IActionResult Index()
        {
            return View();
        }
        
        public IActionResult Privacy()
        {
            return View();
        }
        public IActionResult Login()
        {
            return View();
        }
        [HttpPost]
        public IActionResult Login(string name,string password)
        {
            //string verifyCode = base.HttpContext.Session.GetString("CheckCode");
            //if (verifyCode != null && verifyCode.Equals(verify,
            //    StringComparison.CurrentCultureIgnoreCase))
            //{

            //}
                if ("123".Equals(name) && "123".Equals(password))
                {
                    #region 鉴权:鉴权,检测有没有登录,登录的是谁,赋值给User 
                    //rolelist 是登录成功后用户的角色---是来自于数据库的查询;不同的用户会查询出不同的角色;
                    var rolelist = new List<string>() {
                            "Admin",
                            "Teacher",
                            "Student"
                    };
                    //ClaimTypes.Role就是做权限认证的标识;
                    var claims = new List<Claim>()//鉴别你是谁,相关信息
                    {
                        new Claim(ClaimTypes.Role,"Admin"),
                        new Claim(ClaimTypes.Name,name),
                        new Claim("password",password),//可以写入任意数据
                        new Claim("Account","Administrator"),
                        new Claim("role","admin"),
                        new Claim("admin","admin"),
                    };
                    foreach (var role in rolelist)
                    {
                        claims.Add(new Claim(ClaimTypes.Role, role));
                    }
                    //将用户放在ClaimsPrincipal里面去了;相当身份证,将信息写到身份证里面去;
                    ClaimsPrincipal userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Customer"));
                    HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userPrincipal, new AuthenticationProperties
                    {
                        ExpiresUtc = DateTime.UtcNow.AddMinutes(30),//过期时间:30分钟

                    }).Wait();
                #endregion
                var user = HttpContext.User;
                return base.Redirect("/Home/Privacy");//成功后跳转页面
            }
            else
            {
                base.ViewBag.Msg = "账号或者密码错误";
            }
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }

.NET5鉴权授权--角色授权(角色写死了)
不同的用户,可能会存在不同的角色,不同的角色,可能在访问不同的页面的时候,需要做不同拦截;

角色授权其实就是通过角色不同,做不同的权限拦截;

1.标记的时候,通过逗号分隔不同的角色---只要是有一个角色符合就能够访问,角色之间是或者的关系

 [Authorize(Roles = "Admin,Teacher,Student")]

2.多个特性标记--多个角色之间是且的关系,必须要包含所有的角色,才能够访问

        [Authorize(Roles = "Admin")]
        [Authorize(Roles = "Teacher")]
        [Authorize(Roles = "Student")]

应用实例

1.

2.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(option=> 
                {
                    option.LoginPath = new PathString("/Home/Login");//如果授权失败,就跳转到这个路径
                });

3.Controller

 public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }
       
        public IActionResult Index()
        {
            return View();
        }
        //标记的时候,通过逗号分隔不同的角色---只要是有一个角色符合就能够访问,角色之间是或者的关系
        [Authorize(Roles = "Admin,Teacher,Student")]
        public IActionResult IndexOne()
        {
            return View();
        }
        /// <summary>
        /// 多个特性标记--多个角色之间是且的关系,必须要包含所有的角色,才能够访问
        /// </summary>
        /// <returns></returns>
        [Authorize(Roles = "Admin")]
        [Authorize(Roles = "Teacher")]
        [Authorize(Roles = "Student")]
        public IActionResult IndexTwo()
        {
            return View();
        }
        /// <summary>
        /// 多个特性标记--多个角色之间是且的关系,必须要包含所有的角色,才能够访问
        /// </summary>
        /// <returns></returns>
        [Authorize(Roles = "fellow")]
        [Authorize(Roles = "Teacher")]
        public IActionResult Privacy()
        {
            return View();
        }
        [AllowAnonymousAttribute]
        public IActionResult Login()
        {
            return View();
        }
        [HttpPost]
        [AllowAnonymousAttribute]//匿名--避开权限检查
        public IActionResult Login(string name,string password)
        {
            //string verifyCode = base.HttpContext.Session.GetString("CheckCode");
            //if (verifyCode != null && verifyCode.Equals(verify,
            //    StringComparison.CurrentCultureIgnoreCase))
            //{

            //}
                if ("123".Equals(name) && "123".Equals(password))
                {
                    //登录成功后,此用户对应有多少角色,就能够查询出来

                    #region 鉴权:鉴权,检测有没有登录,登录的是谁,赋值给User 
                    //rolelist 是登录成功后用户的角色---是来自于数据库的查询;不同的用户会查询出不同的角色;
                    var rolelist = new List<string>() {
                            "Admin",
                            "Teacher",
                            "Student"
                    };
                    //ClaimTypes.Role就是做权限认证的标识;
                    var claims = new List<Claim>()//鉴别你是谁,相关信息
                    {
                        new Claim(ClaimTypes.Role,"Admin"),
                        new Claim(ClaimTypes.Name,name),
                        new Claim("password",password),//可以写入任意数据
                        new Claim("Account","Administrator"),
                        new Claim("role","admin"),
                        new Claim("admin","admin"),
                    };
                    foreach (var role in rolelist)
                    {
                        claims.Add(new Claim(ClaimTypes.Role, role));
                    }
                    //将用户放在ClaimsPrincipal里面去了;相当身份证,将信息写到身份证里面去;
                    ClaimsPrincipal userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Customer"));
                    HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userPrincipal, new AuthenticationProperties
                    {
                        ExpiresUtc = DateTime.UtcNow.AddMinutes(30),//过期时间:30分钟

                    }).Wait();
                #endregion
                var user = HttpContext.User;
                return base.Redirect("/Home/Privacy");//成功后跳转页面
            }
            else
            {
                base.ViewBag.Msg = "账号或者密码错误";
            }
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }

.NET5鉴权授权----策略鉴权

上面角色授权是在代码中把角色固定死了;如何能够自己来完成校验逻辑?

1.(1)创建一个类为【CustomAuthorizationHandler】,这个类专用来检验逻辑的,要求继承自【AuthorizationHandler<>】泛型类(泛型类中要求实现【IAuthorizationRequirement】接口)然后在CustomAuthorizationHandler类中实现【HandleRequirementAsync】抽象方法,写逻辑。

就是两个类

 CustomAuthorizationRequirement.cs

 public class CustomAuthorizationRequirement:IAuthorizationRequirement
    {
        public string Name { get; set; }

        public CustomAuthorizationRequirement(string policyName)
        {
            this.Name = policyName;
        }
    }

CustomAuthorizationHander.cs

 public class CustomAuthorizationHander : AuthorizationHandler<CustomAuthorizationRequirement>
    {
        public CustomAuthorizationHander()
        {
        }

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement)
        {
            if (requirement.Name == "Policy01")
            {
                //策略1的逻辑
            }
            if (requirement.Name == "Policy02")
            {
                //策略2的逻辑
            }
            if (requirement.Name == "Policy03")
            {
                //策略3的逻辑
            }
            if (true)
            {

            }

            //在这里可以定义自己的规则
            {
                /*
                 其实这里可以去数据库里面做一些查询,然后根据用户的信息,做计算:如果符合就context.Succd(requirement)
                否则就Task。CompletedTask
                 */
            }

            //context.User 鉴权成功(登录成功后),用户的信息
            var role = context.User.FindFirst(u => u.Value.Contains("admin"));
            if (role != null)
            {
                context.Succeed(requirement);//验证通过了
            }
            return Task.CompletedTask;//验证不通过
        }
    }

2.让自定义逻辑生效: 在ConfigureServices方法中注册进来

services.AddSingleton<IAuthorizationHandler, CustomAuthorizationHander>();

3.在Startup.cs中ConfigureServices方法中注册支持策略授权,也可以支持多种策略认证。

#region 支持多种策略认证
            services.AddAuthorization(options =>
            {
                options.AddPolicy("
customPolicy", policy =>
                {
                    policy.AddRequirements(new CustomAuthorizationRequirement("Policy01"));
                });
            });
            services.AddAuthorization(options =>
            {
                options.AddPolicy("customPolicy01", policy =>
                {
                    policy.AddRequirements(new CustomAuthorizationRequirement("Policy02"));
                });
            });
            services.AddAuthorization(options =>
            {
                options.AddPolicy("customPolicy02", policy =>
                {
                    policy.AddRequirements(new CustomAuthorizationRequirement("Policy03"));
                });
            });
            #endregion

4.使用

  [Authorize(policy: "customPolicy")]
        public IActionResult Privacy()
        {
            return View();
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值