.Net Core AOP之AuthorizeAttribute
一、简介
在.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的更多相关文章
- Asp.net Core AOP实现(采用Autofac)
引用正确的库来实现AOP 新的.NET Core是基于.NET Standard的..所以我们在引用库的时候特别要注意相关的兼容问题. 在传统的ASP.NET中,使用过Autofac来进行AOP操作的 ...
- .Net Core Aop之IResourceFilter
一.简介 在.net core 中Filter分为一下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...
- .Net Core Aop之IActionFilter
一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...
- .Net Core AOP之IResultFilter
一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...
- .Net Core AOP之IExceptionFilter
一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...
- .net core AOP之Filter
当我们进行项目开发时,往往在开发过程中需要临时加入一些常用功能性代码,如身份验证.日志记录.异常获取等功能.如果每个方法中都加入这些功能性代码的话,无疑使项目显得过于臃肿,代码繁杂.这时候就要加入过滤 ...
- ASP.NET Core 认证与授权[5]:初识授权
经过前面几章的姗姗学步,我们了解了在 ASP.NET Core 中是如何认证的,终于来到了授权阶段.在认证阶段我们通过用户令牌获取到用户的Claims,而授权便是对这些的Claims的验证,如:是否拥 ...
- 面向复杂应用,Node.js中的IoC容器 -- Rockerjs/core
Rockerjs Core 项目地址 项目主页 基于 TypeScript 和注解的轻量级IoC容器,提供了依赖注入.面向切面编程及异常处理等功能.Rockerjs Core可在任意工程中引入,是一个 ...
- Spring AOP 中 advice 的四种类型 before after throwing advice around
spring AOP(Aspect-oriented programming) 是用于切面编程,简单的来说:AOP相当于一个拦截器,去拦截一些处理,例如:当一个方法执行的时候,Spring 能够拦截 ...
随机推荐
- Android官方文档翻译 十七 4.1Starting an Activity
Starting an Activity 开启一个Activity This lesson teaches you to 这节课教给你 Understand the Lifecycle Callbac ...
- python 如何获取当前系统的时间
1.导入包 import datetime 2.获取当前的时间 curr_time = datetime.datetime.now() # 2019-07-06 14:55:56.873893 < ...
- 创建一个python类 ,self init相关参数的简单介绍
一 创建 ''' 一 使用python 语法 创建一个类, 探究self 是干啥的 1 创建一个对象 car 2 写入两个行参 3 定义两个方法 ''' class Car(): ''' 二 init ...
- Shiro 简单介绍和快速入门。
一.shiro是啥? /* * Shiro ? 安全框架是一个 1.功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理,并可用于保护任何应用程序 - 从命令行应用程序,移动应用 ...
- Ubuntu更换镜像源
不同的源 当修改sources.list文件时,我们需要将下面任意一个镜像源的代码复制粘贴到该文件中. 阿里源 # 阿里镜像源 deb http://mirrors.aliyun.com/ubuntu ...
- atomic 原子自增工程用法案例
案例 1 : 简单用法 atomic_int id; atomic_fetch_add(&id, 1) atomic_uint id; atomic_fetch_add(&id, 1) ...
- 在Spring Boot中从类路径加载文件
介绍 创建Spring Boot Web应用程序时,有时有时需要从类路径中加载文件:war和jar的加载文件格式是不一样的 在下面,您将找到在WAR和JAR中加载文件的解决方案. 资源加载器 使用Ja ...
- UIKit绘图演练
一般使用UIKit给我们提供的绘图来绘制一些文字,图片这些东西. UIKit给我们提供画图的方法底层也是分为四步.所以也必须在drawRect方法当中去写. 1.如何画文字? ...
- vi/vim 设置.vimrc(/etc/vim | $HOME)
转载请注明来源:https://www.cnblogs.com/hookjc/ "====================================================== ...
- vue element InfiniteScroll 无限滚动 入坑记录
select_law_by_tag() { this.laws_loading.is_loading = true; this.laws_loading.no_more = false; this.e ...