一、简介

在.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. Android官方文档翻译 十七 4.1Starting an Activity

    Starting an Activity 开启一个Activity This lesson teaches you to 这节课教给你 Understand the Lifecycle Callbac ...

  2. python 如何获取当前系统的时间

    1.导入包 import datetime 2.获取当前的时间 curr_time = datetime.datetime.now() # 2019-07-06 14:55:56.873893 < ...

  3. 创建一个python类 ,self init相关参数的简单介绍

    一 创建 ''' 一 使用python 语法 创建一个类, 探究self 是干啥的 1 创建一个对象 car 2 写入两个行参 3 定义两个方法 ''' class Car(): ''' 二 init ...

  4. Shiro 简单介绍和快速入门。

    一.shiro是啥? /* * Shiro ? 安全框架是一个 1.功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理,并可用于保护任何应用程序 - 从命令行应用程序,移动应用 ...

  5. Ubuntu更换镜像源

    不同的源 当修改sources.list文件时,我们需要将下面任意一个镜像源的代码复制粘贴到该文件中. 阿里源 # 阿里镜像源 deb http://mirrors.aliyun.com/ubuntu ...

  6. atomic 原子自增工程用法案例

    案例 1 : 简单用法 atomic_int id; atomic_fetch_add(&id, 1) atomic_uint id; atomic_fetch_add(&id, 1) ...

  7. 在Spring Boot中从类路径加载文件

    介绍 创建Spring Boot Web应用程序时,有时有时需要从类路径中加载文件:war和jar的加载文件格式是不一样的 在下面,您将找到在WAR和JAR中加载文件的解决方案. 资源加载器 使用Ja ...

  8. UIKit绘图演练

    一般使用UIKit给我们提供的绘图来绘制一些文字,图片这些东西.     UIKit给我们提供画图的方法底层也是分为四步.所以也必须在drawRect方法当中去写.     1.如何画文字?      ...

  9. vi/vim 设置.vimrc(/etc/vim | $HOME)

    转载请注明来源:https://www.cnblogs.com/hookjc/ "====================================================== ...

  10. vue element InfiniteScroll 无限滚动 入坑记录

    select_law_by_tag() { this.laws_loading.is_loading = true; this.laws_loading.no_more = false; this.e ...