【问题标题】:Problems with administrator roles: "Access denied"管理员角色的问题:“访问被拒绝”
【发布时间】:2019-06-15 18:31:03
【问题描述】:

我无法将用户管理页面的访问权限授予管理员

我正在学习 ASP .Net Core,但我被困在了这一点上。我查看了代码,确保引用了同名的类,并测试了 Startup.cs 服务的不同配置,但找不到方法。 我正在学习名为“The Little ASP.NET Core Book”的教程。我被困在“角色授权”这一点上

  • 这是我的控制器:

    namespace ASPDotNetCoreTodo.Controllers
    {
    //La configuración de la propiedad Roles en el atributo
    //[Authorize] garantizará que el usuario tenga que iniciar sesión y se le
    //asigne el rol de Administrador para poder ver la página.
    
    [Authorize(Roles = Constants.AdministratorRole)]
    public class ManageUsersController : Controller
    {
        private readonly UserManager<ApplicationUser> _userManager;
    
        public ManageUsersController(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }
        public async Task<IActionResult> Index()
        {
            var admins = (await _userManager
                .GetUsersInRoleAsync("Administrator"))
                .ToArray();
    
            var everyone = await _userManager.Users
                .ToArrayAsync();
    
            var model = new ManageUsersViewModel
            {
                Administrators = admins,
                Everyone = everyone
            };
            return View(model);
        }
    }
    
  • 模型:

    namespace ASPDotNetCoreTodo.Models
    {
        public class ManageUsersViewModel
        {
            public ApplicationUser[] Administrators { get; set; }
            public ApplicationUser[] Everyone { get; set; }
        }
    }
    
  • Startup.cs 文件:

    namespace ASPDotNetCoreTodo
    {
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>                  options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
    
            //  services.AddIdentity<ApplicationUser, IdentityRole>()
            //      .AddEntityFrameworkStores<ApplicationDbContext>()
            //      .AddDefaultTokenProviders();
    
            services.AddDefaultIdentity<ApplicationUser>()
                    .AddRoles<IdentityRole>()
                    .AddEntityFrameworkStores<ApplicationDbContext>()
                    .AddDefaultTokenProviders()
                    ;
    
    
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });
    
        //Añadimos servicio de aplicaciones
            services.AddScoped<ITodoItemService, TodoItemService>();
    
            services.AddAuthentication(); 
    
            services.AddMvc();
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
    
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
    
            app.UseAuthentication();
    
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
    

关键是我在获得授权 ManageUsersController 工作时遇到了麻烦。当在类上方使用 [Authorize(Roles = Constants.AdministratorRole)] 行时,我的测试管理员帐户无法访问该页面,即使使用相同的常量来过滤数据库和菜单中的用户帐户并按预期将它们放在一个表中(在 ManageUsers 视图内)。

我已将 .NET Core 更新到 2.2,并将项目更新到...

不管怎样,这是我的 GitHub:https://github.com/erniker/LearningASPNETCoreAndTests

【问题讨论】:

  • 这是一个非常常见的教程 - 你不需要需要包含这么多细节(例如,using 语句和视图并不能真正帮助解决问题。什么不清楚 - 你怎么知道登录的用户确实是管理员?你有任何错误吗?我无法授予访问权限到底是什么意思?(另外,看看为您完成的格式更改。请确保您的代码可读)
  • 嗨菲利克斯。我知道 de 用户已登录,因为我可以看到每个已登录用户的 TODOlist 页面。我知道我想用来查看“管理用户”页面的用户是管理员,因为你有一个创建管理员帐户的功能……而不是,我没有任何错误;只是当您尝试从管理员帐户查看“管理用户”页面时,我看到的唯一页面是“访问被拒绝”的页面

标签: .net asp.net-mvc asp.net-core


【解决方案1】:

您有管理员登录功能吗?还是一种对用户进行身份验证的方法?

如果不是,那么这就是为什么应用程序在从 cookie 进行身份验证时尝试访问一个用于 Role=Constants.AdministratorRole 的函数(因为您使用了 cookie 身份验证),但是当身份验证尝试检查当前用户时,它会发现没有经过身份验证的用户不允许客户端访问该页面。

考虑以下行动:

  • 首先在 startup.cs 添加身份验证后添加 cookie 策略(显然顺序很重要),并将身份验证方案设置为 cookie 身份验证,以告诉应用程序使用来自 cookie 的身份验证。我通常使用以下内容:

        //add authentication service with an encrypted cookie
        services.AddAuthentication(options => {
    
            options.DefaultScheme = Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultAuthenticateScheme = Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
    
        }).AddCookie(options => {
            options.SlidingExpiration = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
    
            options.Cookie.Name = "ClientCookie";
        });
    
  • 考虑添加登录功能以验证用户为管理员,以便应用可以正确验证用户。我使用这样的东西:

    public class AuthController : Controller
    {
    private readonly string authScheme = Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
    
    
    [HttpPost("[action]")]
    public IActionResult Login([FromBody]JObject body)
    {
    
    
    
        //Gets inputs from Request Body
        string userName = body[UserModelConstants.Username].ToString();
        string password = body[UserModelConstants.Password].ToString();
    
        //use the username and password to check if the user is ok or not
        //then get his claim from database or fill them yourself but make sure to have a role type claim with the value "Administrator" for the admin user
        List<Claim> claims = getUserClaims();
    
        //now you have to create the user identity and principle
        ClaimsIdentity CI = new ClaimsIdentity(claims, Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme, 
            ClaimTypes.Name, ClaimTypes.Role);
        ClaimsPrincipal CP = new ClaimsPrincipal(CI);
    
    
        return SignIn(CP, authScheme);//sign in the user so it can be checked when the user is being authorized to access the function.
    
    }
    

每次我创建项目时,这对我来说都很好,但也许您想根据自己的喜好对其进行一些调整,或者选择其他类型的身份验证。

【讨论】:

  • 嗨哈马迪。感谢您提供的信息,但是,正如您在我的启动过程中看到的那样,我使用 cookie 身份验证。无论如何,我不想在教程之外做任何事情,而且你上面告诉我的一切仍然让我感到困惑...... PD:对不起我的英语不好
  • @JoséPabloMedinaGrande - 你的英语很好;问题是你不想听建议——不是你的英语。您发布的代码中的错误不是;它要么在您的身份验证控制器中,要么在您的中间件配置方式中。你说你知道用户是Administrator;但是应用程序给你 Access denied 错误 - 这表明它不同意你......
  • 抱歉,我很难跟随@Hammadi,建议,但是,我尝试了,但没有成功。我添加了更多信息
【解决方案2】:

好吧,出于任何原因,将.net Core升级到2.2版本后,似乎仍然失败,但是,从VS2019运行项目,而不是VSCode,看来项目运行良好。

【讨论】:

    猜你喜欢
    • 2016-05-20
    • 2018-12-27
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 2023-03-22
    • 2013-02-04
    • 1970-01-01
    相关资源
    最近更新 更多