ASP.NET Core Identity Role:即使定义了角色也出现访问错误

问题描述 投票:0回答:1

在我的项目中,用户区域保留在根侧,管理员区域位于区域中。 两个区域的登录页面、布局和视图都不同。这两个页面的角色设置我该怎么做呢? 我的意思是这样,

admin 端有多个用户,例如 admin A 无法访问 page-1,admin B 无法访问 page-2... 用户端也是同样的方式。

管理员端和用户端应该有单独的AccessDeniedPath路径,如果没有登录,LoginPath应该有单独的路径。

示例:
管理员:管理/登录/索引
用户:登录/索引

我还应该在登录时检查这一点。如果用户由管理员登录,他们应该收到“您未经授权”警告。

这是我尝试过的代码,

使用此代码,我可以在登录时进行控制,但无法创建基于控制器的角色。

程序.cs,

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpClient();
builder.Services.AddControllersWithViews();

builder.Services.AddDbContext<Context>();
builder.Services.AddIdentity<AppUser, AppRole>(options =>
{
    options.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<Context>().AddErrorDescriber<CustomIdentityValidator>().AddDefaultTokenProviders().AddRoles<AppRole>();

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie("UserLogin", options =>
{
    options.LoginPath = "/Login/Index";
    options.Cookie.Name = "UserLoginCookie";
    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
    options.Events = new CookieAuthenticationEvents
    {
        OnValidatePrincipal = context =>
        {
            var now = DateTime.UtcNow;
            var expires = context.Properties.ExpiresUtc;

            if (expires != null && expires.Value < now)
            {
                context.RejectPrincipal();
                context.ShouldRenew = true;
                context.Response.Redirect("/Login/Index");
            }
            return Task.CompletedTask;
        }
    };
})
.AddCookie("ManagementLogin", options =>
{
    options.LoginPath = "/Management/Login/Index";
    options.Cookie.Name = "ManagementLoginCookie";
    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
    options.Events = new CookieAuthenticationEvents
    {
        OnValidatePrincipal = context =>
        {
            var now = DateTime.UtcNow;
            var expires = context.Properties.ExpiresUtc;

            if (expires != null && expires.Value < now)
            {
                context.RejectPrincipal();
                context.ShouldRenew = true;
                context.Response.Redirect("/Management/Login/Index");
            }
            return Task.CompletedTask;
        }
    };
});

builder.Services.AddSession();
builder.Services.AddDistributedMemoryCache();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseSession();

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "areas",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

app.Run();

LoginController.cs,

[AllowAnonymous]
public class LoginController : Controller
{
    private readonly SignInManager<AppUser> _signInManager;
    private readonly UserManager<AppUser> _userManager;

    public LoginController(SignInManager<AppUser> signInManager, UserManager<AppUser> userManager)
    {
        _signInManager = signInManager;
        _userManager = userManager;
    }

    [HttpGet]
    public IActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> Index(LoginDto loginDto)
    {
        LoginValidator validationRules = new LoginValidator();
        ValidationResult validationResult = await validationRules.ValidateAsync(loginDto);
        if (validationResult.IsValid)
        {
            var user = await _userManager.FindByNameAsync(loginDto.UserName);

            if (user != null)
            {
                var result = await _signInManager.CheckPasswordSignInAsync(user, loginDto.Password, true);

                if (result.Succeeded)
                {
                    if (!await _userManager.IsEmailConfirmedAsync(user))
                    {
                        TempData["Mail"] = "Mail";
                        return RedirectToAction("Confirm", "Confirmation");
                    }
                    else
                    {
                        var login = await _signInManager.PasswordSignInAsync(loginDto.UserName, loginDto.Password, true, true);

                        if (login.Succeeded)
                        {
                            if (await _userManager.IsInRoleAsync(user, UserRoles.Kullanici))
                            {
                                var claims = new List<Claim>
                                {
                                    new Claim(ClaimTypes.Name, user.UserName),
                                };

                                var userIdentity = new ClaimsIdentity(claims, "UserLogin");
                                var userPrincipal = new ClaimsPrincipal(userIdentity);

                                await HttpContext.SignInAsync("UserLogin", userPrincipal);

                                return RedirectToAction("Index", "Home");
                            }
                            else
                            {
                                ModelState.AddModelError("", "Bu sayfaya erişim izniniz bulunmamaktadır.");
                                return View();
                            }
                        }
                        else if (login.IsLockedOut)
                        {
                            ModelState.AddModelError("", "Fazla sayıda hatalı giriş yaptığınız için hesabınız kilitlendi. Lütfen daha sonra tekrar deneyiniz. Şifrenizi hatırlamıyorsanız 'Şifremi Unuttum' kısmından yeni bir şifre belirleyebilirsiniz.");
                        }
                        else
                        {
                            ModelState.AddModelError("", "Hatalı Kullanıcı Adı veya Şifre");
                        }
                    }
                }
                else if (result.IsLockedOut)
                {
                    ModelState.AddModelError("", "Fazla sayıda hatalı giriş yaptığınız için hesabınız kilitlendi. Lütfen daha sonra tekrar deneyiniz. Şifrenizi hatırlamıyorsanız 'Şifremi Unuttum' kısmından yeni bir şifre belirleyebilirsiniz.");
                }
                else
                {
                    ModelState.AddModelError("", "Hatalı Kullanıcı Adı veya Şifre");
                }
            }
            else
            {
                ModelState.AddModelError("", "Böyle Bir Hesap Bulunamadı");
            }
        }
        else
        {
            foreach (var item in validationResult.Errors)
            {
                ModelState.AddModelError(item.PropertyName, item.ErrorMessage);
            }
        }
        return View();
    }

    [HttpGet]
    public IActionResult ForgotPassword()
    {
        return View();
    }
}

HomeController.cs,

[Authorize(AuthenticationSchemes = "UserLogin")]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

HomeController.cs(已编辑),

**[Authorize(AuthenticationSchemes = "UserLogin", Roles="User-IT")]**
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

如果我这样使用它,即使我有用户 IT 授权,我也会收到访问被拒绝的警告。

c# sql-server asp.net-mvc asp.net-core asp.net-identity
1个回答
0
投票

您必须在您的声明中添加角色

© www.soinside.com 2019 - 2024. All rights reserved.