在我的项目中,用户区域保留在根侧,管理员区域位于区域中。 两个区域的登录页面、布局和视图都不同。这两个页面的角色设置我该怎么做呢? 我的意思是这样,
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 授权,我也会收到访问被拒绝的警告。
您必须在您的声明中添加角色