ASP.NET MVC создание пользовательского поставщика ролей
будучи относительно новым для ASP MVC, я не уверен, что лучше подойдет моим потребностям. Я построил сайт интрасети с использованием проверки подлинности Windows, и я могу защитить контроллеры и действия, используя роли Active Directory, например
[Authorize(Roles="Administrators")]
[Authorize(Users="DOMAINUser")]
public ActionResult SecureArea()
{
ViewBag.Message = "This is a secure area.";
return View();
}
Мне нужно определить мои собственные роли безопасности независимо от ролей AD. Желаемая функциональность заключается в том, что аутентифицированным пользователям предоставляется доступ к определенным действиям в соответствии с одной или несколькими ролями, связанными с их профилем в my база данных приложений e.g: "менеджер", "пользователь", "гость", "аналитик", "разработчик" и др.
как создать настраиваемый поставщик ролей и / или настраиваемые атрибуты авторизации?
1 ответов
мое решение состояло в создании пользовательского поставщика ролей. Вот шаги, которые я предпринял, если кому-то еще понадобится помощь позже:
создайте свои пользовательские классы пользователей и ролей
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Security.Models.Security
{
public class AppRole : IdentityRole
{
}
}
и
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Security.Models.Security
{
public class AppUser : IdentityUser
{
}
}
настройка контекста базы данных
using Microsoft.AspNet.Identity.EntityFramework;
using Security.Models.Security;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace Security.Models.DAL
{
public class UserContext : IdentityDbContext<AppUser>
{
public UserContext() : base("UserContext")
{
Database.SetInitializer<UserContext>(new CreateDatabaseIfNotExists<UserContext>());
}
}
}
создайте поставщика ролей и реализуйте следующие методы
using Security.Models.DAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
namespace Security.Models.Security
{
public class AppRoleProvider : RoleProvider
{
public override string[] GetAllRoles()
{
using (var userContext = new UserContext())
{
return userContext.Roles.Select(r => r.Name).ToArray();
}
}
public override string[] GetRolesForUser(string username)
{
using (var userContext = new UserContext())
{
var user = userContext.Users.SingleOrDefault(u => u.UserName == username);
var userRoles = userContext.Roles.Select(r => r.Name);
if (user == null)
return new string[] { };
return user.Roles == null ? new string[] { } :
userRoles.ToArray();
}
}
public override bool IsUserInRole(string username, string roleName)
{
using (var userContext = new UserContext())
{
var user = userContext.Users.SingleOrDefault(u => u.UserName == username);
var userRoles = userContext.Roles.Select(r => r.Name);
if (user == null)
return false;
return user.Roles != null &&
userRoles.Any(r => r == roleName);
}
}
}
}
редактировать веб.конфиг настройка соединения с базой данных и ссылки на поставщика ролей
<connectionStrings>
<add name="UserContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\UserContext.mdf;Initial Catalog=UserContext;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>
и
<system.web>
...
<authentication mode="Windows" />
<roleManager enabled="true" defaultProvider="AppRoleProvider">
<providers>
<clear/>
<add name="AppRoleProvider" type="Security.Models.Security.AppRoleProvider" connectionStringName = "UserContext"/>
</providers>
...
</roleManager>
</system.web>
в консоли диспетчера пакетов, включить миграций
enable-migrations
во вновь созданных конфигурациях.cs настройте хранилища и менеджеры пользователей/ролей и настройте валидатор диспетчера пользователей для приема символов"\"
namespace Security.Migrations
{
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Security.Models.Security;
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<Security.Models.DAL.UserContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
ContextKey = "Security.Models.DAL.UserContext";
}
protected override void Seed(Security.Models.DAL.UserContext db)
{
// Set up the role store and the role manager
var roleStore = new RoleStore<AppRole>(db);
var roleManager = new RoleManager<AppRole>(roleStore);
// Set up the user store and the user mananger
var userStore = new UserStore<AppUser>(db);
var userManager = new UserManager<AppUser>(userStore);
// Ensure that the user manager is able to accept special characters for userNames (e.g. '\' in the 'DOMAIN\username')
userManager.UserValidator = new UserValidator<AppUser>(userManager) { AllowOnlyAlphanumericUserNames = false };
// Seed the database with the administrator role if it does not already exist
if (!db.Roles.Any(r => r.Name == "Administrator"))
{
var role = new AppRole { Name = "Administrator" };
roleManager.Create(role);
}
// Seed the database with the administrator user if it does not already exist
if (!db.Users.Any(u => u.UserName == @"DOMAIN\admin"))
{
var user = new AppUser { UserName = @"DOMAIN\admin" };
userManager.Create(user);
// Assign the administrator role to this user
userManager.AddToRole(user.Id, "Administrator");
}
}
}
}
в консоли диспетчера пакетов, убедитесь, что база данных создан и посеян
update-database
создайте пользовательский атрибут авторизации, который перенаправит на страницу запрещенного доступа при сбое
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Security.Models.Security
{
public class AccessDeniedAuthorizationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if(filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectResult("~/Home/AccessDenied");
}
}
}
}
ты молодец! Теперь вы можете создать страницу запрещенного доступа (в этом случае ~ / Home / AccessDenied) и применить атрибут к любому действию, например
using Security.Models.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Security.Controllers
{
public class HomeController : Controller
{
...
[AccessDeniedAuthorizationAttribute(Roles = "Administrator")]
public ActionResult SecureArea()
{
return View();
}
public ActionResult AccessDenied()
{
return View();
}
...
}
}
надеюсь, это поможет кому-то в будущем. Удачи!