Использование магических строк дает вам возможность объявить несколько ролей в атрибуте Authorize (например, [Авторизовать (Roles = «Admin, Moderator»)], которые вы, как правило, теряют, как вы идете строго типизированным решение. Но вот как вы можете сохранить эту гибкость в то же время получать все сильно типизированных
Определите свои роли в перечислении, который использует битовые флаги:.
[Flags]
public enum AppRole {
Admin = 1,
Moderator = 2,
Editor = 4,
Contributor = 8,
User = 16
}
Override AuthorizeAttribute:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyAuthorizeAttribute : AuthorizeAttribute {
public AppRole AppRole { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext) {
if (AppRole != 0)
Roles = AppRole.ToString();
base.OnAuthorization(filterContext);
}
}
Теперь, если вы можете использовать MyAuthorizeAttribute так:
[MyAuthorize(AppRole = AppRole.Admin | AppRole.Moderator | AppRole.Editor)]
public ActionResult Index() {
return View();
}
выше действий будет авторизовать пользователей, которые, по крайней мере, одну из ролей, перечисленных (Admin, Moderator, или редактор). Поведение такое же, как и атрибут AuthorizeAttribute по умолчанию MVC, за исключением без магических строк.
Если вы используете эту технику, вот метод расширения на IPrincipal, которые также могут быть полезны:
public static class PrincipalExtensions {
public static bool IsInRole(this IPrincipal user, AppRole appRole) {
var roles = appRole.ToString().Split(',').Select(x => x.Trim());
foreach (var role in roles) {
if (user.IsInRole(role))
return true;
}
return false;
}
}
Вы можете использовать этот метод расширения, как это:
public ActionResult Index() {
var allowed = User.IsInRole(AppRole.Admin | AppRole.Moderator | AppRole.Editor);
if (!allowed) {
// Do Something
}
return View();
}
Я пошел с этим решением из-за его простоты. Изменения кода были минимальными, так как мне приходилось заменять жестко закодированные строки постоянными ссылками. – MikeWyatt