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 i AuthorizationFilter (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?

Author: Community, 2016-04-06

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.

 35
Author: Tseng,
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.

 1
Author: Shawn,
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