定义类RolePermissionViewModel 保存角色权限
public class RolePermissionViewModel ???{ ???????/// <summary> ???????/// 角色名 ???????/// </summary> ???????public string RoleName { get; set; } ???????/// <summary> ???????/// 请求action ???????/// </summary> ???????public string ActionName { get; set; } ???????/// <summary> ???????/// 请求controller ???????/// </summary> ???????public string ControllerName { get; set; } ???????/// <summary> ???????/// 请求area ???????/// </summary> ???????public string AreaName { get; set; } ???}
定义PermissionRequirement类,实现IAuthorizationRequirement
public class PermissionRequirement:IAuthorizationRequirement ???{ ???????/// <summary> ???????/// 无权限action ???????/// </summary> ???????public string DeniedAction { get; set; } ???????public PermissionRequirement(string deniedAction) ???????{ ???????????DeniedAction = deniedAction; ???????} ???}
定义PermissionHandler类,继承AuthorizationHandler
public class PermissionHandler : Microsoft.AspNetCore.Authorization.AuthorizationHandler<PermissionRequirement> ???{ ???????/// <summary> ???????/// 用户所有权限 ???????/// </summary> ???????public List<RolePermissionViewModel> RolePermission { get; set; } ???????/// <summary> ???????/// 当前方法的名称 ???????/// </summary> ???????private string _actionName = string.Empty; ???????protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) ???????{ ???????????//从AuthorizationHandlerContext转成HttpContext,以便取出表求信息 ?????????????var httpContext = (context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext).HttpContext; ???????????//是否ajax ???????????bool isAjaxCall = httpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest"; ???????????var isAuthenticated = httpContext.User.Identity.IsAuthenticated; ???????????//登陆用户为admin 直接跳过 ???????????if(isAuthenticated) ???????????{ ???????????????var currentUser = httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Name).Value; ???????????????if (currentUser == "admin") ???????????????{ ???????????????????context.Succeed(requirement); ???????????????????return Task.CompletedTask; ???????????????} ???????????} ???????????var authorizationFilterContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext; ???????????//得到Controller类型 ??????????????Type t = (authorizationFilterContext.ActionDescriptor as ControllerActionDescriptor).ControllerTypeInfo; ???????????//得到方法名 ???????????????string actionName = authorizationFilterContext.ActionDescriptor.RouteValues["action"].ToString(); ???????????//得到控制器名 ???????????string controllerName = authorizationFilterContext.ActionDescriptor.RouteValues["controller"].ToString(); ???????????//得到区域名 ???????????string areaName = authorizationFilterContext.ActionDescriptor.RouteValues["area"] == null ? "" : authorizationFilterContext.RouteData.Values["area"].ToString(); ????????????????????????//获取自定义的特性 ???????????????var actionAttribute = (authorizationFilterContext.ActionDescriptor as ControllerActionDescriptor).MethodInfo.GetCustomAttributes(typeof(SetActionAttribute), false).FirstOrDefault() as SetActionAttribute; ????????????????????????_actionName = actionAttribute == null ? actionName : actionAttribute.ActionName; ??????????????????????//请求Url ???????????var questUrl = httpContext.Request.Path.Value.ToLower(); ???????????//是否经过验证 ???????????????????????if (isAuthenticated) ???????????{ ???????????????if (controllerName.ToLower() == "home" ?&& areaName.ToLower() == "admin") ???????????????{ ???????????????????context.Succeed(requirement); ???????????????????return Task.CompletedTask; ???????????????} ???????????????bool hasCurrentControllerRole = RolePermission.GroupBy(g => new { ControllerName = g.ControllerName, ActionName = g.ActionName, AreaName = g.AreaName }).Where(w => w.Key.ActionName.ToLower() == _actionName.ToLower() && w.Key.AreaName.ToLower() == areaName.ToLower() && w.Key.ControllerName.ToLower() == controllerName.ToLower()).Count() > 0; ???????????????if (hasCurrentControllerRole) ???????????????{ ???????????????????//当前用户角色名 ???????????????????var roleName = httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Role).Value.Split(‘,‘); ???????????????????if (RolePermission.Where(w => roleName.Contains(w.RoleName) && w.ControllerName.ToLower() == controllerName.ToLower() && w.ActionName == _actionName.ToLower() && w.AreaName == areaName.ToLower()).Count() > 0) ???????????????????{ ???????????????????????//有权限标记处理成功 ???????????????????????context.Succeed(requirement); ???????????????????} ???????????????} ???????????} ???????????return Task.CompletedTask; ???????} ???}
添加一个用户权限初始化类RolePermissionInit
?public static class RolePermissionInit ???{ ???????public static void Init(IServiceProvider app) ???????{ ???????????PermissionHandler _permissionHandler = app.GetRequiredService<IAuthorizationHandler>() as PermissionHandler; ???????????using (BlogDbContext db = app.GetRequiredService<BlogDbContext>()) ???????????{ ???????????????var roleList = db.SysRoleOperate.Include(s => s.SysRole); ???????????????_permissionHandler.RolePermission = (from r in roleList ????????????????????????????????????????????????????select new RolePermissionViewModel ????????????????????????????????????????????????????{ ????????????????????????????????????????????????????????ActionName = r.Action, ????????????????????????????????????????????????????????AreaName = r.Area, ????????????????????????????????????????????????????????ControllerName = r.Controller, ????????????????????????????????????????????????????????RoleName = r.SysRole.Name ????????????????????????????????????????????????????}).ToList(); ???????????} ???????????????????} ???}
在Program中执行RolePermissionInit.Init
public class Program ???{ ???????public static void Main(string[] args) ???????{ ???????????// BuildWebHost(args).Run(); ???????????????????????var host = BuildWebHost(args) ?????????????.Migrate();//初始化数据 ???????????using (var scope = host.Services.CreateScope()) ???????????{ ???????????????var services = scope.ServiceProvider; ???????????????try ???????????????{ ???????????????????RolePermissionInit.Init(services); ???????????????} ???????????????catch (Exception ex) ???????????????{ ???????????????????var logger = services.GetRequiredService<ILogger<Program>>(); ???????????????????logger.LogError(ex, "An error occurred seeding the DB"); ???????????????} ???????????} ???????????host.Run(); ???????} ???????public static IWebHost BuildWebHost(string[] args) => ???????????WebHost.CreateDefaultBuilder(args) ??????????????.ConfigureAppConfiguration(config => config.AddJsonFile("appsettings.custom.json", optional: true, reloadOnChange: true)) ???????????????.UseStartup<Startup>() ???????????????.Build(); ???}
设置action权限名称特性类SetActionAttribute
public class SetActionAttribute:Attribute{ ????public string ActionName { get; set; }}
Startup类:
ConfigureServices中注入相关配置
services.AddAuthorization(option => { ???????????????option.AddPolicy("Permission", policy => policy.Requirements.Add(new PermissionRequirement("/admin/account/denied"))); ???????????}) ???????????.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) ???????????.AddCookie(option=> { ???????????????option.LoginPath = new PathString("/admin/account/index"); ???????????????option.AccessDeniedPath = new PathString("/admin/account/denied"); ???????????}); ???????????????????????services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
添加自定义授权支持,并添加使用Cookie的方式,配置登录页面和没有权限时的跳转页面。
在Configure中使用
app.UseAuthentication();
使用:
?[Microsoft.AspNetCore.Authorization.Authorize(Policy = "Permission")] ???public class AdminBaseController : Controller ???{ ???????????????public override void OnActionExecuting(ActionExecutingContext context) ???????{ ???????????????????} ???}
登陆验证提交成功后:
//获取用户所有角色 ???????????????var roles = string.Join(",", SysUserRoleService.GetListJoin(s => s.Enable == true&&s.UserId==userinfo.Id, new string[] { "SysRole" }).Select(s => s.SysRole.Name).ToArray()); ???????????????????????????????var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme); ???????????????identity.AddClaim(new Claim(ClaimTypes.Sid, model.LoginName)); ???????????????identity.AddClaim(new Claim(ClaimTypes.Name, userinfo.LoginName)); ???????????????identity.AddClaim(new Claim("RealName", userinfo.RealName)); ???????????????identity.AddClaim(new Claim(ClaimTypes.Role, roles)); ???????????????await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
退出:
public async Task<IActionResult> LoginOut() ???????{ ???????????await HttpContext.SignOutAsync(); ???????????return View("Index"); ???????}
控制器权限控制
[Area("admin")] ???public class BlogManagerController : AdminBaseController ???{ ???????IBlogCategoryService BlogCategoryService { get; set; } ???????IBlogArticleService BlogArticleService { get; set; } ???????public BlogManagerController(IBlogCategoryService blogCategoryService, IBlogArticleService blogArticleService) ???????{ ???????????BlogCategoryService = blogCategoryService; ???????????BlogArticleService = blogArticleService; ???????} ???????public IActionResult Index() ???????{ ?????????????????????return View(); ???????} ???????#region 添加 ???????[HttpGet] ???????public IActionResult Add() ???????{ ???????????var list = BlogCategoryService.GetList(c => c.Enable == true && c.CategoryType == Blog.Models.Enum.BlogCategoryType.General && c.Pid == 0); ???????????var categoryList = (from c in list ???????????????????????????????select new SelectListItem ???????????????????????????????{ ???????????????????????????????????Value = c.Id.ToString(), ???????????????????????????????????Text = c.Name ???????????????????????????????}).ToList(); ???????????ViewBag.categoryList = categoryList; ???????????return PartialView(); ???????} ???????[HttpPost] ???????[SetAction(ActionName ="save")] ???????public IActionResult Add(BlogArticle entity) ???????{ ???????????Response res = null; ???????????if (ModelState.IsValid) ???????????{ ????????????????Request.Form.TryGetValue("childCategory", out StringValues categoryId); ???????????????if (!string.IsNullOrEmpty(categoryId.ToString())) ???????????????{ ???????????????????entity.CategoryId = Convert.ToInt32(categoryId.ToString()); ???????????????} ???????????????entity.Stick = false; ???????????????entity.Recommend = false; ???????????????entity.Submitter = HttpContext.User.Claims.SingleOrDefault(u => u.Type == "RealName").Value; ???????????????entity.Traffic = 0; ???????????????entity.CommentNum = 0; ???????????????entity.CreateTime = DateTime.Now; ???????????????entity.UpdateTime = DateTime.Now; ???????????????entity.CategoryName = BlogCategoryService.Find(c => c.Id == entity.CategoryId).Name; ???????????????res = BlogArticleService.Add(entity); ???????????} ???????????else ???????????{ ???????????????res = new Common.Response() { Code = ResponseCode.Success, Message = Utils.ModelStateMessage(ModelState) }; ???????????} ???????????return Json(res); ???????} ???????#endregion ??????????}
默认使用action名称控制,可以使用[SetAction(ActionName ="save")] 表示当前action需要save保存的权限
参考大牛文章网址:http://www.cnblogs.com/axzxs2001/p/7482771.html
学习Net Core 2.0 做博客 identity登陆权限授权
原文地址:http://www.cnblogs.com/wyzy/p/7749689.html