Cri*_*jak 8 c# asp.net-identity asp.net-core
我有一个ASP.NET Core(完整.NET Framework)应用程序,具有以下配置:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>(p => {
p.Password.RequireDigit = true;
p.Password.RequireNonAlphanumeric = false;
p.Password.RequireUppercase = true;
p.Password.RequiredLength = 5;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.AddTransient<IDbFactory, DbFactory>();
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddTransient<IUserRepository, UserRepository>();
services.AddTransient<IUserService, UserService>();
}
Run Code Online (Sandbox Code Playgroud)
ApplicationUser从IdentityUser扩展而ApplicationDbContext扩展了IdentityDbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base()
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public virtual void Commit()
{
base.SaveChanges();
}
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
base.OnConfiguring(builder);
builder.UseSqlServer("connection string here");
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
// Configure model
// Identity
new Configuration.Identity.ApplicationUserConfiguration(builder.Entity<ApplicationUser>());
new Configuration.Identity.ApplicationUserProfileConfiguration(builder.Entity<ApplicationUserProfile>());
new Configuration.Identity.RoleConfiguration(builder.Entity<IdentityRole>());
new Configuration.Identity.RoleClaimConfiguration(builder.Entity<IdentityRoleClaim<string>>());
new Configuration.Identity.ApplicationUserRoleConfiguration(builder.Entity<IdentityUserRole<string>>());
new Configuration.Identity.ApplicationUserClaimConfiguration(builder.Entity<IdentityUserClaim<string>>());
new Configuration.Identity.ApplicationUserLoginConfiguration(builder.Entity<IdentityUserLogin<string>>());
new Configuration.Identity.ApplicationUserTokenConfiguration(builder.Entity<IdentityUserToken<string>>());
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的演示数据:
角色表
用户表
UserRole表
在我的登录操作中,我有以下内容:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
if (User.IsInRole("Admin"))
{
return RedirectToAction("Index", "Home", new { area = "Admin" });
}
return RedirectToAction("Index", "Home");
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning(2, "User account locked out.");
return View("Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
我想要实现的是在登录后将用户重定向到某个区域.
我面临的当前问题是该函数User.IsInRole("Admin")返回false并且在调试模式下,如果我查看usermanager,则当前用户没有加载角色(Count = 0).
任何想法将不胜感激.
更新1
忽略角色ID原因是错误的.事实上,用户使用正确的值进行映射.
tra*_*max 17
User.IsInRole正在检查cookie.但是您在登录时在同一个http请求中检查此内容.Cookie根本就不存在 - 它将在回复或下一个请求中提供.
此时,您需要使用ApplicationUserManager.IsInRoleAsync(TKey userId, string role)来检查数据库.
如果有人(如我)在.Net Core 2.1中为此苦苦挣扎,则此链接可能会有所帮助。
简而言之,如果您使用的AddDefaultIdentity是这样的:
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
Run Code Online (Sandbox Code Playgroud)
然后,角色将无法使用,因为它们没有在DefaultIdentity中实现。
对我有用的是将其替换为:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
Run Code Online (Sandbox Code Playgroud)
另外,如果您在上述修复之前登录,请注销并再次登录,以便刷新身份声明。现在应该可以了。
经过几个小时的搜索,我在使用Azure Active Directory和Roles时意识到了ASP.Net Core的这项工作
User.HasClaim(ClaimTypes.Role,"admin");
Run Code Online (Sandbox Code Playgroud)
这不
User.IsInRole("admin");
Run Code Online (Sandbox Code Playgroud)
从 .Net Core 2.1 开始(也适用于 3.1),AddDefaultIdentity与调用相同:
AddIdentityAddDefaultUIAddDefaultTokenProviders要添加角色功能,请转到您可以使用的Startup.cs下面,如下所示:ConfigureServices.AddRoles
services.AddDefaultIdentity<IdentityUser>()
.AddRoles<IdentityRole>() //<-- This line
.AddEntityFrameworkStores<ApplicationDbContext>();
Run Code Online (Sandbox Code Playgroud)
这就是所需要的一切。正如上面提到的,注销并重新登录至关重要。
为了记录(并且只是为了测试),我尝试了services.AddIdentity:
IServiceCollection 不包含“AddIdentity”的定义...
并且services.AddIdentityCore(在调试并显示页面之前没有错误):
InvalidOperationException:未指定authenticationScheme,并且未找到DefaultChallengeScheme。可以使用 AddAuthentication(string defaultScheme) 或 AddAuthentication(Action configureOptions) 设置默认方案。
您可能可以做更多的事情来让后两者正常工作,但我发布的代码AddDefaultIdentity是我所需要的,以便让User.IsInRole其他角色功能在 .NET Core 2.1 和迄今为止的 3.1 中工作。
| 归档时间: |
|
| 查看次数: |
6080 次 |
| 最近记录: |