ASP.NET Ядро 5 MVC : глобальная настраиваемая авторизация (.net5.0)

#asp.net-core #asp.net5

Вопрос:

У меня есть свой собственный способ определения ролей, сущностей и разрешений.

Пользователи и их роли определяются в специальном файле таким образом:

 <User login="editor@domain.org" password="secretword" role="Editor" />
 

Структура сайта и разрешения на страницы определены в другом файле:

 ...
<Location url="/docs"Any="n">
    <Location url="/docs/product" Any="n">
        <Location url="/docs/product/introduction" Any="nr" Editor="nrw"/>
..
 

Здесь «Любой» и «Редактор» являются ролями и где: n — может перемещаться, r — может читать, w — может редактировать

Мой сайт не требует авторизации везде, поэтому [Authorize] используется только там, где это необходимо. Для авторизованных пользователей мне нужно проверить их доступ на основе URL-адреса ресурсов, роли пользователя и разрешений ролей.

В настоящее время я сделал это , изменив DefaultAuthorizationService , но я не уверен, что этот подход является лучшим. Есть ли лучшее решение для такого рода проблем?

 public class AuthorizationService : DefaultAuthorizationService {
    Core _core;

    public AuthorizationService(Core core, IAuthorizationPolicyProvider policyProvider,....) : base(policyProvider, ....) {
        _core = core;
    }

    public override Task<AuthorizationResult> AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerable<IAuthorizationRequirement> requirements) {
        var r = base.AuthorizeAsync(user, resource, requirements);

        if(r.Result.Succeeded amp;amp; resource is DefaultHttpContext c) {
            var loc = c.Items[Constants.CurrentPage] as Location; 

            if(loc == null)
                return Task.Run(() => AuthorizationResult.Failed());

            if(loc.Url == "/logout" || loc.Url == "/login") // always allowed   {
                return Task.Run(() => AuthorizationResult.Success());
            }

            // Check where 'user' have 'r' access to 'loc'
            return _core.IsAllowed(user, loc, 'r') ? Task.Run(() => AuthorizationResult.Success()) : Task.Run(() => AuthorizationResult.Failed());
        }
        return r;
    }
}

...
services.AddSingleton<IAuthorizationService, AuthorizationService>();