Jak zaimplementować kontrolę dostępu opartą na uprawnieniach z Asp.Net Rdzeń
[9]}próbuję zaimplementować kontrolę dostępu opartą na uprawnieniach z aspnet core. Do dynamicznego zarządzania rolami i uprawnieniami użytkowników (create_product, delete_product itp.), są przechowywane w bazie danych. Model danych jest jak http://i.stack.imgur.com/CHMPE.png
Przed aspnet core (w MVC 5) używałem custom AuthorizeAttribute
Jak poniżej, aby poradzić sobie z problemem:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
private readonly string _permissionName { get; set; }
[Inject]
public IAccessControlService _accessControlService { get; set; }
public CustomAuthorizeAttribute(string permissionName = "")
{
_permissionName = permissionName;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
var user = _accessControlService.GetUser();
if (PermissionName != "" && !user.HasPermission(_permissionName))
{
// set error result
filterContext.HttpContext.Response.StatusCode = 403;
return;
}
filterContext.HttpContext.Items["CUSTOM_USER"] = user;
}
}
Potem używałem go w metodzie działania jak poniżej:
[HttpGet]
[CustomAuthorize(PermissionEnum.PERSON_LIST)]
public ActionResult Index(PersonListQuery query){ }
Dodatkowo używałem HttpContext.Elementy ["CUSTOM_USER"] w widokach, aby pokazać lub ukryć część html:
@if (CurrentUser.HasPermission("<Permission Name>"))
{
}
Kiedy zdecydowałem się zmienić aspnet core, cały mój plan nie powiódł się. Ponieważ nie było wirtualnej metody OnAuthorization
w AuthorizeAttribute
. Próbowałem rozwiązać problem. Są one poniżej:
-
Korzystanie z nowej autoryzacji opartej na zasadach (myślę, że nie nadaje się do moja sceneria)
-
Używając custom
AuthorizeAttribute
iAuthorizationFilter
(przeczytałem to post https://stackoverflow.com/a/35863514/5426333 Ale ja Couldn ' t change it properly) Korzystanie z custom middleware(jak uzyskać
AuthorizeAttribute
z bieżącego akcja?)Używanie ActionFilter(czy jest poprawne ze względów bezpieczeństwa?)
Nie mogłem się zdecydować, która droga jest najlepsza dla mojego scenerio i jak ją wdrożyć.
Pierwsze pytanie: czy implementacja MVC5 jest złą praktyką?
Drugie pytanie: czy macie jakieś propozycje wdrożenia aspnet core?
2 answers
Na podstawie komentarzy, tutaj przykład jak korzystać z autoryzacji opartej na zasadach:
public class PermissionRequirement : IAuthorizationRequirement
{
public PermissionRequirement(PermissionEnum permission)
{
Permission = permission;
}
public PermissionEnum Permission { get; }
}
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
private readonly IUserPermissionsRepository permissionRepository;
public PermissionHandler(IUserPermissionsRepository permissionRepository)
{
if(permissionRepository == null)
throw new ArgumentNullException(nameof(permissionRepository));
this.permissionRepository = permissionRepository;
}
protected override void Handle(AuthorizationContext context, PermissionRequirement requirement)
{
if(context.User == null)
{
// no user authorizedd. Alternatively call context.Fail() to ensure a failure
// as another handler for this requirement may succeed
return null;
}
bool hasPermission = permissionRepository.CheckPermissionForUser(context.User, requirement.Permission);
if (hasPermission)
{
context.Succeed(requirement);
}
}
}
I zapisać go w swojej klasie Startup
:
services.AddAuthorization(options =>
{
UserDbContext context = ...;
foreach(var permission in context.Permissions)
{
// assuming .Permission is enum
options.AddPolicy(permission.Permission.ToString(),
policy => policy.Requirements.Add(new PermissionRequirement(permission.Permission)));
}
});
// Register it as scope, because it uses Repository that probably uses dbcontext
services.AddScope<IAuthorizationHandler, PermissionHandler>();
I wreszcie w kontrolerze
[HttpGet]
[Authorize(Policy = PermissionEnum.PERSON_LIST.ToString())]
public ActionResult Index(PersonListQuery query)
{
...
}
Zaletą tego rozwiązania jest to, że możesz również mieć wiele programów obsługi dla danego wymogu, tzn. jeśli pierwszy z nich się powiedzie, drugi program obsługi może określić, że nie powiódł się i możesz go używać z autoryzacją opartą na zasobach przy niewielkim wysiłku.
Polityka oparta podejście jest preferowanym sposobem, aby to zrobić przez ASP.NET Główna drużyna.
From blowdart :
Nie chcemy, abyś pisał własne atrybuty autoryzacji. Jeśli musisz to zrobić, zrobiliśmy coś złego. Zamiast tego powinieneś pisać wymagania autoryzacyjne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-16 15:31:33
Rozwiązanie, które nie wymaga dodawania polityki dla każdego uprawnienia, zobacz moją ODPOWIEDŹ na inne pytanie.
Pozwala ozdobić kontrolery i akcje dowolnymi niestandardowymi atrybutami i uzyskać do nich dostęp W autoryzacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:42