【问题标题】:Custom role based auth .NET CORE基于自定义角色的身份验证 .NET CORE
【发布时间】:2021-02-21 11:02:41
【问题描述】:

我有一个项目,其中用户可以担任多个角色,例如收银员和股票文员。这些角色具有相同的权限,但也可以有管理员和收银员的角色。在这种情况下,他可以访问比管理员/收银员更多的功能。

我进行了广泛的搜索,但我从文档中没有得到任何更明智的信息,因为我最初认为政策是要走的路,但现在我认为我们需要基于声明的授权。

在搜索和玩耍后,我没有找到以下问题的答案:

  1. 我需要哪些表/实体?
  2. 可以在没有脚手架工具的情况下完成吗?
  3. 整个过程是如何工作的,.NET CORE 是如何知道要看什么角色的?如何使用自定义角色?

如果有人能帮我解决这个问题,我将不胜感激。

干杯。

【问题讨论】:

    标签: asp.net-core .net-core authorization claims-based-identity claims-authentication


    【解决方案1】:

    一种方法是使用身份并使用[Authorize(Roles ="Admin")] 授权用户。

    如果你不想使用脚手架工具,你可以使用 jwt 令牌认证或 cookie 认证。

    这是一个关于如何使用cookie认证的简单演示:

    型号:

    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
        public List<UserRole> UserRoles { get; set; }
    }
    public class Role
    {
        public int Id { get; set; }
        public string RoleName { get; set; }
        public List<UserRole> UserRoles { get; set; }
    }
    public class UserRole
    {
        public int UserId { get; set; }
        public User User { get; set; }
        public int RoleId { get; set; }
        public Role Role { get; set; }
    }
    public class LoginModel
    {
        public string Name { get; set; }
        public string Password { get; set; }
    }
    

    控制器:

    public class HomeController : Controller
    {
        private readonly YouDbContext _context;
    
        public HomeController(YouDbContext context)
        {
            _context = context;
        }
        public IActionResult Login()
        {
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> Login(LoginModel model)
        {
            var claims = new List<Claim>{};
            var user = _context.User
                               .Include(u=>u.UserRoles)
                               .ThenInclude(ur=>ur.Role)
                               .Where(m => m.Name == model.Name).FirstOrDefault();
            if(user.Password==model.Password)
            {
                foreach(var role in user.UserRoles.Select(a=>a.Role.RoleName))
                {
                    var claim = new Claim(ClaimTypes.Role, role);
                    claims.Add(claim);
                }               
                var claimsIdentity = new ClaimsIdentity(
                    claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
                var authProperties = new AuthenticationProperties{};
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    new ClaimsPrincipal(claimsIdentity),
                    authProperties);
            }
            return View("Index");
        }       
        public IActionResult Index()
        {
            return View();
        }
    
        //allow Cashier
        [Authorize(Roles = "Cashier")]
        public IActionResult Privacy()
        {
            return View();
        }
    
        //allow Admin
        [Authorize(Roles = "Admin")]
        public IActionResult AllowAdmin()
        {
            return View();
        }
    
        //allow both of the Admin and Cashier
        [Authorize(Roles = "Admin,Cashier")]
        public IActionResult AllowBoth()
        {
            return View();
        }
    
        //user has no rights to access the page
        public IActionResult AccessDenied()
        {
            return View();
        }
    
        //log out
        public async Task<IActionResult> Logout()
        {
            await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);
            return RedirectToAction("Index");
        }        
    }
    

    数据库上下文:

    public class YouDbContext: DbContext
    {
        public YouDbContext(DbContextOptions<YouDbContext> options)
            : base(options)
        {
        }
    
        public DbSet<User> User { get; set; }
        public DbSet<Role> Role { get; set; }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<UserRole>()
       .HasKey(bc => new { bc.UserId, bc.RoleId });
            modelBuilder.Entity<UserRole>()
                .HasOne(bc => bc.User)
                .WithMany(b => b.UserRoles)
                .HasForeignKey(bc => bc.UserId);
            modelBuilder.Entity<UserRole>()
                .HasOne(bc => bc.Role)
                .WithMany(c => c.UserRoles)
                .HasForeignKey(bc => bc.RoleId);
        }
    }
    

    Startup.cs:

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                    .AddCookie(options =>
                    {
                        options.LoginPath = "/Home/Login";
                        options.AccessDeniedPath = "/Home/AccessDenied";
                    });
            services.AddDbContext<WebApplication1Context>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("WebApplication1Context")));
        }
    
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseHttpsRedirection();
            app.UseStaticFiles();
    
            app.UseRouting();
    
            app.UseAuthentication();
            app.UseAuthorization();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
    

    结果:

    【讨论】:

    • 感谢您的详细回答。正是我想要的。我仍然认为文档对此并不清楚,而且对我来说很难理解。干杯。
    猜你喜欢
    • 2017-08-26
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多