c# - net core 5 Authentication 设置两个登录路径
问题描述
在我的 net core 5 应用程序中,我需要设置两个登录路径,一个用于管理区域的管理员,另一个用于用户区域,我已经配置了应用程序 cookie,但我无法访问 ConfigureServices 中的当前 url,所以我无法更改登录路径取决于网址
我的代码
public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration _config)
{
AppIdentitySettings appIdentitySettings = _config.GetSection("AppIdentitySettings").Get<AppIdentitySettings>();
services.AddIdentity<CI_User, CI_Role>(opt =>
{
//password settings
opt.Password.RequiredLength = appIdentitySettings.Password.RequiredLength;
opt.Password.RequireDigit = appIdentitySettings.Password.RequireDigit;
opt.Password.RequiredUniqueChars = appIdentitySettings.Password.RequiredUniqueChars;
opt.Password.RequireUppercase = appIdentitySettings.Password.RequireUppercase;
opt.Password.RequireLowercase = appIdentitySettings.Password.RequireLowercase;
opt.Password.RequireNonAlphanumeric = appIdentitySettings.Password.RequireNonAlphanumeric;
//user settings
//opt.User.AllowedUserNameCharacters = "ghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP";
opt.User.RequireUniqueEmail = appIdentitySettings.User.RequireUniqueEmail;
//Lockout settings
//opt.Lockout.AllowedForNewUsers = false;
})
.AddEntityFrameworkStores<_ModelsContext>()
.AddDefaultTokenProviders();
//configure cookie
services.ConfigureApplicationCookie(opt =>
{
// Cookie settings
opt.Cookie.HttpOnly = true;
opt.ExpireTimeSpan = TimeSpan.FromMinutes(60);
opt.LoginPath = "/ar/Home/App";
opt.AccessDeniedPath = "/Identity/Account/AccessDenied";
opt.SlidingExpiration = true;
});
return services;
}
这种情况我该怎么办!?
- - - - - 更新 - - - - -
我找到了两种解决方案,或者您可以将其称为解决方法
解决方案一:在启动ConfigureServices中添加两种不同的Authentication scheme
string defaultCulture = _config.GetValue<string>("DefaultCulture");
services.AddAuthentication(opt => { opt.DefaultScheme = "UserAuth"; })
.AddCookie("UserAuth", opt =>
{
opt.LoginPath = $"/{defaultCulture}/User/Login";
opt.AccessDeniedPath = $"/{defaultCulture}/Account/AccessDenied/";
})
.AddCookie("AdminAuth", opt =>
{
opt.LoginPath = $"/{defaultCulture}/Admin/About";
opt.AccessDeniedPath = $"/{defaultCulture}/Admin/Account/AccessDenied/";
});
并用于使用
[Authorize(AuthenticationSchemes = "AdminAuth")]
解决方案一的问题:如果您有一个多语言应用程序,您无法将用户动态重定向到他选择的文化
解决方案二:添加自定义授权属性
public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter
{
public bool IsAdmin { get; set; } = false;
public void OnAuthorization(AuthorizationFilterContext context)
{
bool hasAllowAnonymous = context.ActionDescriptor.EndpointMetadata.Any(em => em.GetType() == typeof(AllowAnonymousAttribute));
bool isAuth = context.HttpContext.User.Identity.IsAuthenticated;
if (!isAuth && !hasAllowAnonymous)
{
string redirectUrl = context.HttpContext.Request.Path.Value;
if (IsAdmin)
context.Result = new RedirectToActionResult("Index", "About", new { redirectUrl = redirectUrl, area = "Admin" });
else
context.Result = new RedirectToActionResult("App", "Home", new { redirectUrl = redirectUrl });
}
}
}
解决方案二的问题:如果你从 Authorize 属性继承,你不能做同样的逻辑,所以你将失去所有的 authorize 属性的好处!
解决方案
if (_env.IsDevelopment())
{
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Account/AdminLogin";
});
}
else
{
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Account/Login";
});
}
[AllowAnonymous]
[Route("Account")]
public class AccountController : Controller
{
[Route("Login")]
public IActionResult Login()
{
return Redirect("Your login path");
}
[Route("AdminLogin")]
public async Task<IActionResult> AdminLogin()
{
if (_env.IsDevelopment())
await _signInManager.PasswordSignInAsync("admin user name", "admin password", true, false);
return Redirect("Your login path");
}
}
推荐阅读
- android - React Navigation 适用于 Android 虚拟设备,但不适用于真实的 Android 设备
- python - python3菱形继承如何作用于数据字段?如何用 super()._init__ 初始化继承的字段?
- python - 如何将循环函数创建的值插入到 tkinter 文本框中,这些文本框也是使用循环函数自动创建的
- flutter - 如何在 Flutter 中使用分组元素进行无限滚动分页?
- javascript - 修复 Heroku 503 超时
- hyperledger-fabric - 使用 node.js 应用程序调用链码时无法连接到发现的排序器
- ios - 自定义电容器插件因 pod 依赖性而失败
- sql-server - 如果该表的适当ID存在于另一个表中,我想汇总特定表列中的所有数据
- python - 熊猫从绳子上取下零件
- c++ - C++多继承虚函数如何访问派生类字段?