一、简介

在.net core 中Filter分为以下六大类:

1、AuthorizeAttribute(权限验证)

2、IResourceFilter(资源缓存)

3、IActionFilter(执行方法前后的记录)

4、IResultFilter(结果生成前后扩展)

5、IAlwaysRun(响应结果的补充)

6、IExceptionFilter(异常处理)

二、AuthorizeAttribute(权限验证)

认证授权分为三种,如下:

1、基于角色授权

1.1、配置Startup.cs 类,使用Cookie及角色授权方式访问 —— 修改 ConfigureServices 与 Configure方法

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(); {
// ************1、添加鉴权和授权逻辑**************************
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.LoginPath = new PathString("/Login/LoginView"); // 登录地址
options.AccessDeniedPath = new PathString("/Login/AccessDenied"); // 无权限访问需要跳转的页面地址
options.LogoutPath = new PathString("/Login/LoginOff"); // 登出地址
options.ExpireTimeSpan = TimeSpan.FromMinutes(1); // cookie有效时间(这里设置的1分钟有效时间)
options.Cookie = new CookieBuilder
{
// cookie名称,Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")取得是当前环境变量的名称,用户可自定义
Name = $"WebUI_{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}"
};
});
services.AddAuthorization();
// **********************************************************
}
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); app.UseRouting(); // ***************2、鉴权*******************
app.UseAuthentication();
// 授权
app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Login}/{action=LoginView}/{id?}");
});
}

1.2、使用授权的时候在Action或controller上打上Authorize特性并赋值Role属性,表示该方法只能由Admin的角色访问

public class LoginController : Controller
{
// 登录页面
public IActionResult LoginView()
{
return View();
} /// <summary>
/// 登录方法
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public async Task<IActionResult> Login()
{ var claims = new List<Claim>
{
new Claim(ClaimTypes.Name,"xiaohemiao"),
new Claim(ClaimTypes.Role,"Admin")
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme
, new ClaimsPrincipal(claimsIdentity)
, new AuthenticationProperties()
{
ExpiresUtc = DateTime.UtcNow.AddMinutes(1)
}); return Redirect("/Login/Index");
} /// <summary>
/// 登录成功之后跳转的页面
/// </summary>
/// <returns></returns>
[Authorize(Roles = "Admin")]
public IActionResult Index()
{
return View();
} /// <summary>
/// 登出
/// </summary>
/// <returns></returns>
public async Task<IActionResult> LoginOff()
{
await HttpContext.SignOutAsync();
return Redirect("/Login/LoginView");
} /// <summary>
/// 无权限页面
/// </summary>
/// <returns></returns>
public IActionResult AccessDenied()
{
return View();
} }

2、基于声明授权

修改基于标题1的相关代码

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(); {
// ************1、添加鉴权和授权逻辑**************************
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.LoginPath = new PathString("/Login/LoginView"); // 登录地址
options.AccessDeniedPath = new PathString("/Login/AccessDenied"); // 无权限访问需要跳转的页面地址
options.LogoutPath = new PathString("/Login/LoginOff"); // 登出地址
options.ExpireTimeSpan = TimeSpan.FromMinutes(1); // cookie有效时间(这里设置的1分钟有效时间)
options.Cookie = new CookieBuilder
{
// cookie名称,Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")取得是当前环境变量的名称,用户可自定义
Name = $"WebUI_{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}"
};
});
services.AddAuthorization(options => {
// 当角色是Admin和SuperAdministrator才可以访问
options.AddPolicy("AdministratorOnly", policy => policy.RequireClaim(ClaimTypes.Role, "Admin", "SuperAdministrator"));
});
// **********************************************************
}
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); app.UseRouting(); // ***************2、鉴权*******************
app.UseAuthentication();
// 授权
app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Login}/{action=LoginView}/{id?}");
});
}
public class LoginController : Controller
{
// 登录页面
public IActionResult LoginView()
{
return View();
} /// <summary>
/// 登录方法
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public async Task<IActionResult> Login()
{ var claims = new List<Claim>
{
new Claim(ClaimTypes.Name,"xiaohemiao"),
new Claim(ClaimTypes.Role,"Admin")
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme
, new ClaimsPrincipal(claimsIdentity)
, new AuthenticationProperties()
{
ExpiresUtc = DateTime.UtcNow.AddMinutes(1)
}); return Redirect("/Login/Index");
} /// <summary>
/// 登录成功之后跳转的页面
/// </summary>
/// <returns></returns>
[Authorize(Policy = "AdministratorOnly")]
public IActionResult Index()
{
return View();
} /// <summary>
/// 登出
/// </summary>
/// <returns></returns>
public async Task<IActionResult> LoginOff()
{
await HttpContext.SignOutAsync();
return Redirect("/Login/LoginView");
} /// <summary>
/// 无权限页面
/// </summary>
/// <returns></returns>
public IActionResult AccessDenied()
{
return View();
} }

3、自定义策略授权

3.1、定义权限策略

public class PermissionRequirement: IAuthorizationRequirement
{ }

3.2、再定义个策略处理类

public class RoleAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
{
private readonly ILogger<RoleAuthorizationHandler> _logger;
private readonly IHttpContextAccessor _httpContextAccessor; public RoleAuthorizationHandler(ILogger<RoleAuthorizationHandler> logger, IHttpContextAccessor httpContextAccessor)
{
_logger = logger;
this._httpContextAccessor = httpContextAccessor;
}
public override Task HandleAsync(AuthorizationHandlerContext context)
{
var mvcContext = _httpContextAccessor.HttpContext;
var user = context.User.FindFirst(ClaimTypes.Role)?.Value; if (mvcContext.User.Identity.IsAuthenticated)
{
var routes = mvcContext.GetRouteData();
var controller = routes.Values["controller"]?.ToString()?.ToLower();
var action = routes.Values["action"]?.ToString()?.ToLower(); var activeTime = mvcContext.User.FindFirst(ClaimTypes.Expired);
// 是否登录超时
if (activeTime == null || Convert.ToDateTime(activeTime.Value) < DateTime.Now)
{
// 登录超时自动跳转到登录页面
mvcContext.Response.Redirect("/Login/LoginView");
context.Succeed(context.Requirements.FirstOrDefault());
return Task.CompletedTask;
} var hasRole = mvcContext.User.HasClaim(c => c.Type == ClaimTypes.Role);
if (!hasRole)
{
//用户未在系统添加,即使登录成功,也要提示没有权限
context.Fail();
return Task.CompletedTask;
} var menuPaths = AuthorizationMenuPath(user);
string route = $"/{controller}"; var actionRoute = $"/{controller}/{(routes.Values["action"] ?? "Index")}".ToLower();
if (menuPaths.Any(m => m.ToLower().Contains($"/{controller}/")) || menuPaths.Any(m => m.ToLower() == route) || menuPaths.Any(m => m.ToLower() == actionRoute))
context.Succeed(context.Requirements.FirstOrDefault());
else context.Fail();//会默认跳转 accessdenied视图 }
else
context.Fail(); return Task.CompletedTask;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
throw new NotImplementedException();
} /// <summary>
/// 权限动态缓存类 临时替代数据库
/// </summary>
/// <param name="roleName">角色名称</param>
/// <returns></returns>
private List<string> AuthorizationMenuPath(string roleName)
{
switch (roleName)
{
case "Admin":
return new List<string>() { "/Login/Index" };
default:
return new List<string>() { "/Login/Index" };
} }
}

3.3、修改 ConfigureServices 与 Configure方法

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(); { // ************3、注入自定义策略**************************
services.AddSingleton<IAuthorizationHandler, RoleAuthorizationHandler>();
// ************1、添加鉴权和授权逻辑**************************
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.LoginPath = new PathString("/Login/LoginView"); // 登录地址
options.AccessDeniedPath = new PathString("/Login/AccessDenied"); // 无权限访问需要跳转的页面地址
options.LogoutPath = new PathString("/Login/LoginOff"); // 登出地址
options.ExpireTimeSpan = TimeSpan.FromMinutes(1); // cookie有效时间(这里设置的1分钟有效时间)
options.Cookie = new CookieBuilder
{
// cookie名称,Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")取得是当前环境变量的名称,用户可自定义
Name = $"WebUI_{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}"
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("RolePolicy", policy =>policy.Requirements.Add(new PermissionRequirement())); }); services.AddHttpContextAccessor();
// **********************************************************
}
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); app.UseRouting(); // ***************2、鉴权*******************
app.UseAuthentication();
// 授权
app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Login}/{action=LoginView}/{id?}");
});
}

3.4 、controller代码逻辑

public class LoginController : Controller
{
// 登录页面
public IActionResult LoginView()
{
return View();
} /// <summary>
/// 登录方法
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public async Task<IActionResult> Login()
{ var claims = new List<Claim>
{
new Claim(ClaimTypes.Name,"xiaohemiao"),
new Claim(ClaimTypes.Role,"Admin"),
new Claim(ClaimTypes.Expired,DateTime.Now.AddMinutes(1).ToString("yyyy-MM-dd HH:mm:ss")) };
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme
, new ClaimsPrincipal(claimsIdentity)
, new AuthenticationProperties()
{ }); return Redirect("/Login/Index");
} /// <summary>
/// 登录成功之后跳转的页面
/// </summary>
/// <returns></returns>
[Authorize(Policy = "RolePolicy")]
public IActionResult Index()
{
return View();
} /// <summary>
/// 登出
/// </summary>
/// <returns></returns>
public async Task<IActionResult> LoginOff()
{
await HttpContext.SignOutAsync();
return Redirect("/Login/LoginView");
} /// <summary>
/// 无权限页面
/// </summary>
/// <returns></returns>
public IActionResult AccessDenied()
{
return View();
} }

三、简单页面呈现效果

1、登录页面

2、登录成功跳转的页面

3、无权限页面

.Net Core AOP之AuthorizeAttribute的更多相关文章

  1. Asp.net Core AOP实现(采用Autofac)

    引用正确的库来实现AOP 新的.NET Core是基于.NET Standard的..所以我们在引用库的时候特别要注意相关的兼容问题. 在传统的ASP.NET中,使用过Autofac来进行AOP操作的 ...

  2. .Net Core Aop之IResourceFilter

    一.简介 在.net core 中Filter分为一下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...

  3. .Net Core Aop之IActionFilter

    一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...

  4. .Net Core AOP之IResultFilter

    一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...

  5. .Net Core AOP之IExceptionFilter

    一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...

  6. .net core AOP之Filter

    当我们进行项目开发时,往往在开发过程中需要临时加入一些常用功能性代码,如身份验证.日志记录.异常获取等功能.如果每个方法中都加入这些功能性代码的话,无疑使项目显得过于臃肿,代码繁杂.这时候就要加入过滤 ...

  7. ASP.NET Core 认证与授权[5]:初识授权

    经过前面几章的姗姗学步,我们了解了在 ASP.NET Core 中是如何认证的,终于来到了授权阶段.在认证阶段我们通过用户令牌获取到用户的Claims,而授权便是对这些的Claims的验证,如:是否拥 ...

  8. 面向复杂应用,Node.js中的IoC容器 -- Rockerjs/core

    Rockerjs Core 项目地址 项目主页 基于 TypeScript 和注解的轻量级IoC容器,提供了依赖注入.面向切面编程及异常处理等功能.Rockerjs Core可在任意工程中引入,是一个 ...

  9. Spring AOP 中 advice 的四种类型 before after throwing advice around

    spring  AOP(Aspect-oriented programming) 是用于切面编程,简单的来说:AOP相当于一个拦截器,去拦截一些处理,例如:当一个方法执行的时候,Spring 能够拦截 ...

随机推荐

  1. MATLAB中回归模型

    (1).一元线性回归:数学模型定义      模型参数估计   检验.预测及控制 1.回归模型:   可线性化的一元非线性回归    (2).多元线性回归:数学模型定义 模型参数估计 多元线性回归中检 ...

  2. 从零开始, 开发一个 Web Office 套件 (2): 富文本编辑器

    书接前文: 从零开始, 开发一个 Web Office 套件 (1): 富文本编辑器 这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Of ...

  3. 微服务架构 | 4.2 基于 Feign 与 OpenFeign 的服务接口调用

    目录 前言 1. OpenFeign 基本知识 1.1 Feign 是什么 1.2 Feign 的出现解决了什么问题 1.3 Feign 与 OpenFeign 的区别与对比 2. 在服务消费者端开启 ...

  4. 学习Java第17天

    今天差不多搞清了Javaweb的基本学习路线及网站开发的基本流程,以前好像走了不少弯路,不过还好,明天开始学习Javaweb sql 总结了许多 新的学习方法,记笔记很重要,学多少忘多少. 练习也很重 ...

  5. HTML 基础3

    表格 示例1: <h4>水平表头+普通边框</h4> <table border="1"> <caption>caption标签展示 ...

  6. 如何在 VS Code 中为 Java 类生成序列化版本号

    前言 IDEA 提供自动生成序列化版本号的功能,其实 VS Code 也可以,只是默认关闭了这个功能,下面就来看看如何开启这个功能吧. 配置过程 首先需要保证 VS Code 上安装了提供 Java ...

  7. Maven仓库的目录结构

    _remote.repositories文件 本地库中的包都有一个_remote.repositories文件,示例: #NOTE: This is an Aether internal implem ...

  8. JDBC工具包commons-dbutils的基本介绍

    感谢原文作者:simonXi-tech 原文链接:https://blog.csdn.net/simonforfuture/article/details/90480147 更多请查阅在线API文档: ...

  9. Linux shell脚本之 if条件判断 (转)

    IF条件判断 1.基本语法: if [ command ]; then 符合该条件执行的语句 fi 2.扩展语法: if [ command ];then 符合该条件执行的语句 elif [ comm ...

  10. axios取消接口请求

    axios取消请求 这里就是分析一下接口请求需要被取消时的一些操作 因为我是用vue写的项目,所以标配用的是axios,怎么在axios中取消已经发送的请求呢? 1.在这之前我们还是先介绍一下原生js ...