net core 5认证设置两个登录路径



在我的net core 5应用程序中,我需要设置两个登录路径,一个用于管理员区域,另一个用于用户区域,我已经配置了应用程序cookie,但我无法访问ConfigureServices中的当前url,因此我无法更改登录路径取决于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;
}

我怎么能做到这种情况!?

---------- 更新 ---------

我已经找到了两个解决方案,或者你可以称之为变通

解决方案一个:在start - up ConfigureServices

中添加两种不同的认证方案
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 });
}
}
}

解决方案二的问题:如果您继承了授权属性,则不能执行相同的逻辑,因此您将失去授权属性的所有好处!

我使用这个解决方案在管理区有额外的登录页面:

services.ConfigureApplicationCookie(options =>
{
options.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = redirectContext =>
{
// Area's own login page
const string area = "/Admin";
if (redirectContext.Request.Path.StartsWithSegments(area))
{
var uriBuilder = new UriBuilder(redirectContext.RedirectUri);
uriBuilder.Path = area + uriBuilder.Path;
redirectContext.RedirectUri = uriBuilder.ToString();
}
return Task.CompletedTask;
}
};
});

这是我在尝试了认证方案后发现的最简单的方法。

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");
}
}

最新更新