码迷,mamicode.com
首页 > Web开发 > 详细

学习Net Core 2.0 做博客 identity登陆权限授权

时间:2017-10-29 12:54:13      阅读:304      评论:0      收藏:0      [点我收藏+]

标签:ppc   msi   json   update   bsp   www.   from   用户权限   ade   

定义类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登陆权限授权

标签:ppc   msi   json   update   bsp   www.   from   用户权限   ade   

原文地址:http://www.cnblogs.com/wyzy/p/7749689.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!