Ich verwende die Standardwebsite-Vorlage von asp.net core und die Authentifizierung, die als individuelles Benutzerkonto ausgewählt wurde. Wie kann ich eine Rolle erstellen und dem Benutzer zuweisen, damit ich die Rolle im Controller zum Filtern des Zugriffs verwenden kann?.
Ich habe im Kontocontroller eine Aktion erstellt, die eine Funktion aufruft, um die Rollen zu erstellen und die Administratorrolle für einen Standardbenutzer zu beeinflussen (Sie sollten wahrscheinlich den Standardbenutzer in der Produktion entfernen):
private async Task createRolesandUsers()
{
bool x = await _roleManager.RoleExistsAsync("Admin");
if (!x)
{
// first we create Admin rool
var role = new IdentityRole();
role.Name = "Admin";
await _roleManager.CreateAsync(role);
//Here we create a Admin super user who will maintain the website
var user = new ApplicationUser();
user.UserName = "default";
user.Email = "[email protected]";
string userPWD = "somepassword";
IdentityResult chkUser = await _userManager.CreateAsync(user, userPWD);
//Add default User to Role Admin
if (chkUser.Succeeded)
{
var result1 = await _userManager.AddToRoleAsync(user, "Admin");
}
}
// creating Creating Manager role
x = await _roleManager.RoleExistsAsync("Manager");
if (!x)
{
var role = new IdentityRole();
role.Name = "Manager";
await _roleManager.CreateAsync(role);
}
// creating Creating Employee role
x = await _roleManager.RoleExistsAsync("Employee");
if (!x)
{
var role = new IdentityRole();
role.Name = "Employee";
await _roleManager.CreateAsync(role);
}
}
Nachdem Sie einen Controller zum Verwalten der Rollen für die Benutzer erstellen konnten.
Mein Kommentar wurde gelöscht, weil ich einen Link zu einer ähnlichen Frage angegeben habe, die ich beantwortet habe hier . Ergo, ich werde es diesmal genauer beantworten. Hier geht.
Sie können dies einfach tun, indem Sie eine CreateRoles
-Methode in Ihrer startup
-Klasse erstellen. Auf diese Weise können Sie überprüfen, ob die Rollen erstellt wurden, und die Rollen erstellen, wenn dies nicht der Fall ist. beim Start der Anwendung. Wie so.
private async Task CreateRoles(IServiceProvider serviceProvider)
{
//initializing custom roles
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
string[] roleNames = { "Admin", "Manager", "Member" };
IdentityResult roleResult;
foreach (var roleName in roleNames)
{
var roleExist = await RoleManager.RoleExistsAsync(roleName);
if (!roleExist)
{
//create the roles and seed them to the database: Question 1
roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
}
}
//Here you could create a super user who will maintain the web app
var poweruser = new ApplicationUser
{
UserName = Configuration["AppSettings:UserName"],
Email = Configuration["AppSettings:UserEmail"],
};
//Ensure you have these values in your appsettings.json file
string userPWD = Configuration["AppSettings:UserPassword"];
var _user = await UserManager.FindByEmailAsync(Configuration["AppSettings:AdminUserEmail"]);
if(_user == null)
{
var createPowerUser = await UserManager.CreateAsync(poweruser, userPWD);
if (createPowerUser.Succeeded)
{
//here we tie the new user to the role
await UserManager.AddToRoleAsync(poweruser, "Admin");
}
}
}
und dann können Sie die CreateRoles(serviceProvider).Wait();
-Methode von der Configure
-Methode in der Startup-Klasse aufrufen. Stellen Sie sicher, dass Sie IServiceProvider
als Parameter in der Klasse Configure
haben.
Verwenden der rollenbasierten Autorisierung in einem Controller zum Filtern des Benutzerzugriffs: Frage 2
Sie können dies leicht tun, wie so.
[Authorize(Roles="Manager")]
public class ManageController : Controller
{
//....
}
Sie können auch die rollenbasierte Autorisierung in der Aktionsmethode wie folgt verwenden. Weisen Sie gegebenenfalls mehrere Rollen zu
[Authorize(Roles="Admin, Manager")]
public IActionResult Index()
{
/*
.....
*/
}
Dies funktioniert zwar einwandfrei, für eine weitaus bessere Vorgehensweise sollten Sie sich jedoch über die Verwendung richtlinienbasierter Rollenprüfungen informieren. Sie finden es in der ASP.NET-Kerndokumentation hier oder in diesem Artikel, den ich darüber geschrieben habe hier
Temis Antwort ist fast richtig, aber Sie können eine asynchrone Funktion nicht von einer nicht asynchronen Funktion aufrufen, wie er es vorschlägt. Was Sie tun müssen, ist, asynchrone Aufrufe in einer synchronen Funktion wie folgt durchzuführen:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
// Add external authentication middleware below. To configure them please see https://go.Microsoft.com/fwlink/?LinkID=532715
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
CreateRoles(serviceProvider);
}
private void CreateRoles(IServiceProvider serviceProvider)
{
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
Task<IdentityResult> roleResult;
string email = "[email protected]";
//Check that there is an Administrator role and create if not
Task<bool> hasAdminRole = roleManager.RoleExistsAsync("Administrator");
hasAdminRole.Wait();
if (!hasAdminRole.Result)
{
roleResult = roleManager.CreateAsync(new IdentityRole("Administrator"));
roleResult.Wait();
}
//Check if the admin user exists and create it if not
//Add to the Administrator role
Task<ApplicationUser> testUser = userManager.FindByEmailAsync(email);
testUser.Wait();
if (testUser.Result == null)
{
ApplicationUser administrator = new ApplicationUser();
administrator.Email = email;
administrator.UserName = email;
Task<IdentityResult> newUser = userManager.CreateAsync(administrator, "[email protected]!");
newUser.Wait();
if (newUser.Result.Succeeded)
{
Task<IdentityResult> newUserRole = userManager.AddToRoleAsync(administrator, "Administrator");
newUserRole.Wait();
}
}
}
Der Schlüssel dazu ist die Verwendung der Task <> -Klasse und das Erzwingen, dass das System synchron auf etwas andere Weise wartet.
Ich benutze dies (DI):
public class IdentitySeed
{
private readonly ApplicationDbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _rolesManager;
private readonly ILogger _logger;
public IdentitySeed(
ApplicationDbContext context,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
ILoggerFactory loggerFactory) {
_context = context;
_userManager = userManager;
_rolesManager = roleManager;
_logger = loggerFactory.CreateLogger<IdentitySeed>();
}
public async Task CreateRoles() {
if (await _context.Roles.AnyAsync()) {// not waste time
_logger.LogInformation("Exists Roles.");
return;
}
var adminRole = "Admin";
var roleNames = new String[] { adminRole, "Manager", "Crew", "Guest", "Designer" };
foreach (var roleName in roleNames) {
var role = await _rolesManager.RoleExistsAsync(roleName);
if (!role) {
var result = await _rolesManager.CreateAsync(new ApplicationRole { Name = roleName });
//
_logger.LogInformation("Create {0}: {1}", roleName, result.Succeeded);
}
}
// administrator
var user = new ApplicationUser {
UserName = "Administrator",
Email = "[email protected]",
EmailConfirmed = true
};
var i = await _userManager.FindByEmailAsync(user.Email);
if (i == null) {
var adminUser = await _userManager.CreateAsync(user, "Something*");
if (adminUser.Succeeded) {
await _userManager.AddToRoleAsync(user, adminRole);
//
_logger.LogInformation("Create {0}", user.UserName);
}
}
}
//! By: Luis Harvey Triana Vega
}
Neben der Antwort von Temi Lajumoke sollte beachtet werden, dass nach dem Erstellen der erforderlichen Rollen und dem Zuweisen dieser Rollen zu bestimmten Benutzern in der ASP.NET Core 2.1 MVC-Webanwendung Nach dem Starten der Anwendung tritt möglicherweise ein Methodenfehler auf, z. B. beim Registrieren oder Verwalten eines Kontos:
InvalidOperationException: Der Dienst für den Typ "Microsoft.AspNetCore.Identity.UI.Services.IEmailSender" kann nicht aufgelöst werden, während versucht wird, "WebApplication.Areas.Identity.Pages.Account.Manage.IndexModel" zu aktivieren.
Ein ähnlicher Fehler kann in der ConfigureServices-Methode schnell behoben werden, indem die AddDefaultUI () -Methode hinzugefügt wird:
services.AddIdentity<IdentityUser, IdentityRole>()
//services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
Prüfen
https://blogs.msdn.Microsoft.com/webdev/2018/03/02/aspnetcore-2-1-identity-ui/
und verwandtes Thema auf Github:
https://github.com/aspnet/Docs/issues/6784 für weitere Informationen.
Und zum Zuweisen einer Rolle zu einem bestimmten Benutzer könnte die IdentityUser-Klasse anstelle von ApplicationUser verwendet werden.
Der folgende Code funktioniert mit ISA.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory,
IServiceProvider serviceProvider)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
// Add external authentication middleware below. To configure them please see https://go.Microsoft.com/fwlink/?LinkID=532715
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
CreateRolesAndAdminUser(serviceProvider);
}
private static void CreateRolesAndAdminUser(IServiceProvider serviceProvider)
{
const string adminRoleName = "Administrator";
string[] roleNames = { adminRoleName, "Manager", "Member" };
foreach (string roleName in roleNames)
{
CreateRole(serviceProvider, roleName);
}
// Get these value from "appsettings.json" file.
string adminUserEmail = "[email protected]";
string adminPwd = "[email protected]!";
AddUserToRole(serviceProvider, adminUserEmail, adminPwd, adminRoleName);
}
/// <summary>
/// Create a role if not exists.
/// </summary>
/// <param name="serviceProvider">Service Provider</param>
/// <param name="roleName">Role Name</param>
private static void CreateRole(IServiceProvider serviceProvider, string roleName)
{
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
Task<bool> roleExists = roleManager.RoleExistsAsync(roleName);
roleExists.Wait();
if (!roleExists.Result)
{
Task<IdentityResult> roleResult = roleManager.CreateAsync(new IdentityRole(roleName));
roleResult.Wait();
}
}
/// <summary>
/// Add user to a role if the user exists, otherwise, create the user and adds him to the role.
/// </summary>
/// <param name="serviceProvider">Service Provider</param>
/// <param name="userEmail">User Email</param>
/// <param name="userPwd">User Password. Used to create the user if not exists.</param>
/// <param name="roleName">Role Name</param>
private static void AddUserToRole(IServiceProvider serviceProvider, string userEmail,
string userPwd, string roleName)
{
var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
Task<ApplicationUser> checkAppUser = userManager.FindByEmailAsync(userEmail);
checkAppUser.Wait();
ApplicationUser appUser = checkAppUser.Result;
if (checkAppUser.Result == null)
{
ApplicationUser newAppUser = new ApplicationUser
{
Email = userEmail,
UserName = userEmail
};
Task<IdentityResult> taskCreateAppUser = userManager.CreateAsync(newAppUser, userPwd);
taskCreateAppUser.Wait();
if (taskCreateAppUser.Result.Succeeded)
{
appUser = newAppUser;
}
}
Task<IdentityResult> newUserRole = userManager.AddToRoleAsync(appUser, roleName);
newUserRole.Wait();
}