Еще один интересный кейс из рабочей практики.
В нашем фреймворке есть мощный механизм для аутентификации и авторизации, можно использовать ролевую модель или более новую на базе клеймов. Есть IAuthorizationService
С методом
AuthorizeAsync(ClaimsPrincipal, Object, String)
Соответственно, мы можем сделать свой набор прав
public class AuthorizationRequirement
{
public class CanViewRequirement : IAuthorizationRequirement { }
}
Создать политику
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CanViewPolicy", policy =>
policy.AddRequirements(new AuthorizationRequirement.CanViewRequirement()));
});
И создать свой хэндлер
public class CustomAuthorizationHandler : AuthorizationHandler
{
…
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
AuthorizationRequirement.CanViewRequirement requirement,
Model resource)
{
///
}
…
}
И наконец вызывать на конкретном ресурсе (Model), очень просто и красиво
var authResult = await _authorizationService.AuthorizeAsync(User, OurObject, "CanViewPolicy");
if (!authResult.Succeeded)
{
return Forbid();
}
Кто не знал такого – знайте, что так можно. Возможно, кто-то спросит зачем это, ведь есть и ролевка, и клеймы, и можно делать свои аттрибуты и отклонять запросы на уровне эндпоинтов?
А я отвечу: часто, особенно во всяких корпоративных CRM, доступ строится динамически исходя из конкретного пользователя и конкретного ресурса, куда запрашивается доступ. Банальный пример, флоу какого-то документа в документообороте. Тут понятно, что подписывает руководитель, какие-то промежуточные визы ставят связанные службы (юристы, экономисты, и т.д.), но вот доступ к какому-то документу, или файлу, или действию может только инициатор, а еще чаще требуется чтобы доступ имел инициатор и его непосредственный руководитель.
И вот как раз для таких сценариев очень удобно использовать этот механизм, обращаемся к ресурсру, смотрим кто автор, смотрим куда-то в 1C / AD – кто там руководитель, смотрим потом уже в контекст Http запроса и определяем, а можно ли отдать документ или нет.
В нашем фреймворке есть мощный механизм для аутентификации и авторизации, можно использовать ролевую модель или более новую на базе клеймов. Есть IAuthorizationService
С методом
AuthorizeAsync(ClaimsPrincipal, Object, String)
Соответственно, мы можем сделать свой набор прав
public class AuthorizationRequirement
{
public class CanViewRequirement : IAuthorizationRequirement { }
}
Создать политику
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CanViewPolicy", policy =>
policy.AddRequirements(new AuthorizationRequirement.CanViewRequirement()));
});
И создать свой хэндлер
public class CustomAuthorizationHandler : AuthorizationHandler
{
…
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
AuthorizationRequirement.CanViewRequirement requirement,
Model resource)
{
///
}
…
}
И наконец вызывать на конкретном ресурсе (Model), очень просто и красиво
var authResult = await _authorizationService.AuthorizeAsync(User, OurObject, "CanViewPolicy");
if (!authResult.Succeeded)
{
return Forbid();
}
Кто не знал такого – знайте, что так можно. Возможно, кто-то спросит зачем это, ведь есть и ролевка, и клеймы, и можно делать свои аттрибуты и отклонять запросы на уровне эндпоинтов?
А я отвечу: часто, особенно во всяких корпоративных CRM, доступ строится динамически исходя из конкретного пользователя и конкретного ресурса, куда запрашивается доступ. Банальный пример, флоу какого-то документа в документообороте. Тут понятно, что подписывает руководитель, какие-то промежуточные визы ставят связанные службы (юристы, экономисты, и т.д.), но вот доступ к какому-то документу, или файлу, или действию может только инициатор, а еще чаще требуется чтобы доступ имел инициатор и его непосредственный руководитель.
И вот как раз для таких сценариев очень удобно использовать этот механизм, обращаемся к ресурсру, смотрим кто автор, смотрим куда-то в 1C / AD – кто там руководитель, смотрим потом уже в контекст Http запроса и определяем, а можно ли отдать документ или нет.